鉴于我有一个像这样调用函数doStuff
的类:
const myService = require(`./myService`),
service = new myService();
exports.doStuff = async (callback) => {
try {
const data = await service.doOtherStuff(); //I want to mock this
return callback(null, data);
} catch (err) {
callback(new Error(` > feed failed for ${key}, error: ${err}`));
}
};
我的测试是这样的:
const myClass = require(`../index`);
jest.mock(`./../myService`, () => {
return function() {
return {
doOtherStuff: () => {
return 1;
}
};
};
});
describe(`service-tests - index`, () => {
test(`doStuff and test otherStuff`, async () => {
const result = await myClass.doStuff((err, data) => {
return data;
});
expect(result).toBe(1);
});
});
我的服务:
class myService{
constructor() {
//Do constructor stuff
}
async doOtherStuff() {
//Do other stuff
}
这可以工作,但是现在我只是对该文件进行了模拟,而不是通过测试。 我需要的是让我的模拟可以逐个测试进行更改,但似乎无法弄清楚它如何与require一起工作。
我尝试只做jest.mock('./../myService')
并将mockImplementation
放在beforeAll
上,但这会使我的函数像自动模拟一样被模拟,返回 undefined
有人做过吗?
答案 0 :(得分:2)
如果您要模拟类中的方法(看起来像您正在做的那样),建议您使用jest.spyOn。很简单,您可以将返回值模拟为每次测试所需的值。
ffmpeg -i 1.mp4 -i logo.png -i picture.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-20:20[bg];[bg][2:v]overlay=10:10[v]" -map "[v]" -map 0:a -c:a copy output.mp4
答案 1 :(得分:1)
更新
由于这两种方法都可以工作,并且它们可能有用,因此我将在这里留下答案。
...但是对于这种特殊情况,@ Daniel是正确的,模拟原型方法最简单
一种简单的处理方法是将myService.js
模拟为单例...
...然后,您可以获取doOtherStuff
的模拟功能并根据每次测试进行更改:
const myClass = require(`../index`);
jest.mock(`../myService`, () => {
const doOtherStuff = jest.fn(); // <= create a mock function for doOtherStuff
const result = { doOtherStuff };
return function() { return result; }; // <= always return the same object
});
const doOtherStuff = require('./myService')().doOtherStuff; // <= get doOtherStuff
describe(`service-tests - index`, () => {
test(`doStuff and test otherStuff`, async () => {
doOtherStuff.mockReturnValue(1); // <= mock it to return something
const result = await myClass.doStuff((err, data) => data);
expect(result).toBe(1); // Success!
});
test(`doStuff and test otherStuff`, async () => {
doOtherStuff.mockReturnValue('something else'); // <= mock it to return something else
const result = await myClass.doStuff((err, data) => data);
expect(result).toBe('something else'); // Success!
});
});
它还可以自动模拟myService.js
并使用mockImplementation
...
...但是由于index.js
在运行后立即创建了一个myService
实例 ,因此您必须确保在之前您需要index.js
:
jest.mock(`../myService`); // <= auto-mock
const myService = require('../myService');
const doOtherStuff = jest.fn();
myService.mockImplementation(function() { return { doOtherStuff }; });
const myClass = require(`../index`); // <= now require index
describe(`service-tests - index`, () => {
test(`doStuff and test otherStuff`, async () => {
doOtherStuff.mockReturnValue(1); // <= mock it to return something
const result = await myClass.doStuff((err, data) => data);
expect(result).toBe(1); // Success!
});
test(`doStuff and test otherStuff`, async () => {
doOtherStuff.mockReturnValue('something else'); // <= mock it to return something else
const result = await myClass.doStuff((err, data) => data);
expect(result).toBe('something else'); // Success!
});
});