Node.js 开玩笑+;MockImplementationOnce+;第二次不工作了
我正在使用JEST框架对node.js项目进行单元测试。我使用mockImplementationOnce模拟第三方库方法,如下所示: 开玩笑的模仿('abc',()=>{ 返回{a:{b:jest.fn()}; }); const abcjs=需要(“abc”) 第一个测试成功执行,但第二个测试调用实际方法,而不是模拟。Node.js 开玩笑+;MockImplementationOnce+;第二次不工作了,node.js,unit-testing,jestjs,Node.js,Unit Testing,Jestjs,我正在使用JEST框架对node.js项目进行单元测试。我使用mockImplementationOnce模拟第三方库方法,如下所示: 开玩笑的模仿('abc',()=>{ 返回{a:{b:jest.fn()}; }); const abcjs=需要(“abc”) 第一个测试成功执行,但第二个测试调用实际方法,而不是模拟。 我尝试在每次之后重置模拟,但都没有帮助。我昨天在模拟aws sdk时遇到了同样的问题 事实证明,在模拟了整个模块一次之后,就不能在同一个文件中再次重写该模拟的行为 我很惊讶您
我尝试在每次之后重置模拟,但都没有帮助。我昨天在模拟aws sdk时遇到了同样的问题 事实证明,在模拟了整个模块一次之后,就不能在同一个文件中再次重写该模拟的行为 我很惊讶您的第一个测试居然通过了,尽管您的默认模拟函数只是一个没有任何返回值的jest.fn()。 这里有一个完整的讨论- 线程的最终解决方案:
//不模拟整个模块
const abcjs=需要(“abc”);
描述(“第一次测试”,()=>{
测试(“应返回true”,异步()=>{
//尝试使用jest.spyOn()而不是jest.fn
jest.spyOn(abcjs.a,'b').mockImplementationOnce(()=>Promise.resolve(true));
//这里的expect语句
});
});
描述(“第二次测试”,()=>{
jest.restoreAllMocks();//{
jest.spyOn(abcjs.a,'b').mockImplementationOnce(()=>Promise.resolve(false));
//这里的expect语句
});
});
基本上,不要模拟整个模块,而只模拟您想要从中获得的功能。也许这可以作为您的参考。如果是我,那么想法是这样的: 将其视为您所指的第三方库方法
/**
* Module dependencies.
*/
const abcjs = {
a: { b: () => null }
}
然后我想象的测试场景是
describe('a test scenario', () => {
afterEach(() => {
// Restores all mocks back to their original value.
// only works when the mock was created with jest.spyOn;
jest.restoreAllMocks()
})
describe('1st test', () => {
test('should return true', async () => {
jest.spyOn(abcjs.a, 'b').mockImplementation()
/**
* Accepts a value that will be returned for one call to the mock function. Can be chained so that
* successive calls to the mock function return different values. When there are no more
* `mockResolvedValueOnce` values to use, calls will return a value specified by `mockResolvedValueOnce`.
*/
abcjs.a.b.mockResolvedValueOnce(true).mockResolvedValueOnce('isTrue')
let resultExpected = await abcjs.a.b()
// Ensures that a mock function is called an exact number of times.
expect(abcjs.a.b).toHaveBeenCalledTimes(1)
// Used when you want to check that two objects have the same value.
expect(resultExpected).toEqual(true)
// try to invoked the function for second times...
resultExpected = await abcjs.a.b()
// Ensures that a mock function is called an exact number of times...
// which is the second time !
expect(abcjs.a.b).toHaveBeenCalledTimes(2)
// Used when you want to check that two objects have the same value.
expect(resultExpected).toEqual('isTrue')
})
})
describe('2nd test', () => {
test('should return false', async () => {
jest.spyOn(abcjs.a, 'b').mockImplementation()
abcjs.a.b.mockResolvedValueOnce(false)
const resultExpected = await abcjs.a.b()
expect(abcjs.a.b).toHaveBeenCalledTimes(1)
expect(resultExpected).toEqual(false)
})
})
})
如果是我,我宁愿用这个来回报承诺
mockFn.mockResolvedValue(value)
或mockFn.mockRejectedValue(value)
而不是mockImplementation(()=>Promise.resolve(value))
这只是我可以描述的一种测试方法。希望这能给你一个想法。但我还是收到了同样的错误。现在我在第一个测试用例本身中收到错误。现在第二个测试显示调用ctrl函数时模拟方法未定义。我已经更新了我的答案,使用
jest.spyOn
,而不是jest.fn
,并在最后标记mockImplementationOnce
,如图所示-实际上我正在使用spyOn进行实验。但对于第二次测试来说,这并不是嘲笑。它调用实际的方法。当我们需要添加jest.restoreAllMocks()时也是如此;无论是现在还是以后,每一种事情都会发生???jest.restoreAllMocks
将函数还原为其在被模拟之前的原始功能。因此,如果您愿意,可以在每次之后将其放入。此外,只要您再次模拟您的函数,您的第二次测试也应该通过。你能在你的问题中更新你的代码吗?
describe('a test scenario', () => {
afterEach(() => {
// Restores all mocks back to their original value.
// only works when the mock was created with jest.spyOn;
jest.restoreAllMocks()
})
describe('1st test', () => {
test('should return true', async () => {
jest.spyOn(abcjs.a, 'b').mockImplementation()
/**
* Accepts a value that will be returned for one call to the mock function. Can be chained so that
* successive calls to the mock function return different values. When there are no more
* `mockResolvedValueOnce` values to use, calls will return a value specified by `mockResolvedValueOnce`.
*/
abcjs.a.b.mockResolvedValueOnce(true).mockResolvedValueOnce('isTrue')
let resultExpected = await abcjs.a.b()
// Ensures that a mock function is called an exact number of times.
expect(abcjs.a.b).toHaveBeenCalledTimes(1)
// Used when you want to check that two objects have the same value.
expect(resultExpected).toEqual(true)
// try to invoked the function for second times...
resultExpected = await abcjs.a.b()
// Ensures that a mock function is called an exact number of times...
// which is the second time !
expect(abcjs.a.b).toHaveBeenCalledTimes(2)
// Used when you want to check that two objects have the same value.
expect(resultExpected).toEqual('isTrue')
})
})
describe('2nd test', () => {
test('should return false', async () => {
jest.spyOn(abcjs.a, 'b').mockImplementation()
abcjs.a.b.mockResolvedValueOnce(false)
const resultExpected = await abcjs.a.b()
expect(abcjs.a.b).toHaveBeenCalledTimes(1)
expect(resultExpected).toEqual(false)
})
})
})