如何使用Jasmine模拟在另一个模块中所需的模块

6
const Client = require('./src/http/client');

module.exports.handler = () => {
    const client = new Client();
    const locationId = client.getLocationId(123);
};

我该如何在Jasmine中测试这个模块,以确保client.getLocationId已经被调用并传入了参数123
我知道如何使用Sinon来实现,但对于Jasmine却一无所知。
1个回答

5

如果使用 Sinon,您需要执行以下操作:

Sinon.spy(client, 'getLocationId');

...

Sinon.assert.calledWith(client.getLocationId, 123);

使用Jasmine,您可以:
spyOn(client, 'getLocationId');

...

expect(client.getLocationId).toHaveBeenCalledWith(123);

更新: 所以,您需要模拟被测试模块所需的Client模块。我建议使用Proxyquire来实现这一点:

const proxyquire = require('proxyquire');
const mockedClientInstance = {
  getLocationId: () => {}
};
const mockedClientConstructor = function() {
  return mockedClientInstance;
};

const moduleToTest = proxyquire('moduleToTest.js', {
  './src/http/client': mockedClientConstructor
});

这将把你的模拟对象注入为依赖项,这样当你测试的模块需要./src/http/client时,它会得到你的模拟对象而不是真正的Client模块。之后,你可以像平常一样在mockedClientInstance中对方法进行间谍监视:
spyOn(mockedClientInstance, 'getLocationId');
moduleToTest.handler();
expect(mockedClientInstance.getLocationId).toHaveBeenCalledWith(123);

问题在于我的测试中无法访问client实例,因此我无法对任何方法进行间谍操作。 - kekko12
1
@kekko12 嗯,这应该不会影响Sinon和Jasmine之间的任何区别。你提到你知道如何使用Sinon实现它。你会怎么做呢?任何解决方案都应该可以在Jasmine中正常工作。 - Lennholm
其实我以为我知道,但是我刚试了一下,发现不起作用。它只有在所需的模块是一个实例(单例)时才有效。我想唯一的选择就是使用Proxyquire。 - kekko12
proxyquire是正确的选择。 - user566245

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接