我是Jest的新手。我设法嘲笑自己的东西,但似乎是在模仿一个模块。特别是构造函数。
usage.js
const AWS = require("aws-sdk")
cw = new AWS.CloudWatch({apiVersion: "2010-08-01"})
...
function myMetrics(params) {
cw.putMetricData(params, function(err, data){})
}
我想在测试中做这样的事情。
const AWS = jest.mock("aws-sdk")
class FakeMetrics {
constructor() {}
putMetricData(foo,callback) {
callback(null, "yay!")
}
}
AWS.CloudWatch = jest.fn( (props) => new FakeMetrics())
但是当我在usage.js
中使用它时,cw是mockConstructor
而不是FakeMetrics
我意识到我的方法可能不如惯用语'所以我对任何指针都很满意。
这是一个最小的例子https://github.com/ollyjshaw/jest_constructor_so
npm install -g jest
jest
答案 0 :(得分:10)
问题是如何模拟模块。正如the reference所述,
在需要时模拟具有自动模拟版本的模块。 < ...> 返回链接的jest对象。
AWS
不是模块对象,而是jest
对象,分配AWS.CloudFormation
不会影响任何内容。
此外,它在一个地方CloudWatch
,在另一个地方CloudFormation
。
测试框架不需要重新发明模拟函数,它们已经存在。它应该是这样的:
const AWS = require("aws-sdk");
const fakePutMetricData = jest.fn()
const FakeCloudWatch = jest.fn(() => ({
putMetricData: fakePutMetricData
}));
AWS.CloudWatch = FakeCloudWatch;
断言如:
expect(fakePutMetricData).toHaveBeenCalledTimes(1);
答案 1 :(得分:4)
以上回答有效。但是,在与 jest 一起工作了一段时间之后,我只会使用 mockImplementation 功能,该功能对于模拟构造函数很有用。
下面的代码可能是一个示例:
import * as AWS from 'aws-sdk';
jest.mock('aws-sdk', ()=> {
return {
CloudWatch : jest.fn().mockImplementation(() => { return {} })
}
});
test('AWS.CloudWatch is callled', () => {
new AWS.CloudWatch();
expect(AWS.CloudWatch).toHaveBeenCalledTimes(1);
});
请注意,在示例中,新的CloudWatch()仅返回一个空对象。
答案 2 :(得分:0)
根据documentation mockImplementation
也可以用来模拟类构造函数:
// SomeClass.js
module.exports = class SomeClass {
m(a, b) {}
};
// OtherModule.test.js
jest.mock('./SomeClass'); // this happens automatically with automocking
const SomeClass = require('./SomeClass');
const mMock = jest.fn();
SomeClass.mockImplementation(() => {
return {
m: mMock,
};
});
const some = new SomeClass();
some.m('a', 'b');
console.log('Calls to m: ', mMock.mock.calls);