如何在玩笑中重置或清除间谍?

我有一个间谍,在一个套件的多个测试中用于多个断言。

如何清除或重置间谍,以便在每个测试中,间谍拦截的方法被认为没有被调用?

例如,如何使 'does not run method'中的断言为真?

const methods = {
run: () => {}
}


const spy = jest.spyOn(methods, 'run')


describe('spy', () => {
it('runs method', () => {
methods.run()
expect(spy).toHaveBeenCalled() //=> true
})


it('does not run method', () => {
// how to make this true?
expect(spy).not.toHaveBeenCalled() //=> false
})
})
113423 次浏览

Jest 间谍拥有与模拟相同的 API。模拟的文档是 给你,并指定了一个方法 mockClear,其中:

重置存储在 mockFn.mock.callsmockFn.mock.instances数组中的所有信息。

当您想要 在两个断言之间清理 mock 的使用数据时,这通常是有用的。

(强调我自己)

因此,我们可以使用 mockClear来“重置”一个间谍。使用你的例子:

const methods = {
run: () => {}
}


const spy = jest.spyOn(methods, 'run')


describe('spy', () => {
it('runs method', () => {
methods.run()
expect(spy).toHaveBeenCalled() //=> true
/* clean up the spy so future assertions
are unaffected by invocations of the method
in this test */
spy.mockClear()
})


it('does not run method', () => {
expect(spy).not.toHaveBeenCalled() //=> true
})
})

下面是 CodeSandbox 中的一个示例。

感谢@sdgluck 提供的答案,不过我想在这个答案中添加一点,在我的例子中,我希望每次测试之后都有一个清晰的状态,因为我对同一个间谍进行了多次测试。因此,我没有在以前的测试中调用 mockClear(),而是将它移到了 afterEach()中(或者您可以与 beforeEach一起使用它) ,如下所示:

afterEach(() => {
jest.clearAllMocks();
});

最后,我的测试工作正常,没有间谍被称为以前的测试。你也可以读他们的 文件为它

选择二

如果希望从全局级别进行更新,也可以更新 jest.config.js(或从 package.json)

module.exports = {
clearMocks: true,
// ...
}

你可以读到有关它的笑话 文件

在@ghiscode 的回答上进一步迭代,您可以在 Jest 配置中指定 clearMocks,这相当于在每个测试之间调用 jest.clearAllMocks():

{
...
clearMocks: true,
...
}

看看文件 给你

如果您希望恢复以前添加到间谍中的方法的原始行为,可以使用 mock Restore 方法。

看看下面的例子:

class MyClass {
get myBooleanMethod(): boolean {
return true;
}
}


const myObject = new MyClass();
const mockMyBooleanMethod = jest.spyOn(myObject, 'myBooleanMethod', 'get');
// mock myBooleanMethod to return false
mockMyBooleanMethod.mockReturnValue(false);
// restore myBooleanMethod to its original behavior
mockMyBooleanMethod.mockRestore();

在 jest.config.js 中,添加 mock Reset ——不是 clearMocks,因为它不会删除测试之间的任何模拟实现(也就是说,mock Reset 是更为谨慎的选项,它会删除测试之间的实现——在我看来,这是正确的做法,因为每个测试都应该是孤立的)。

{
...
mockReset: true,
...
}