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

Posted

技术标签:

【中文标题】如何在 Jest 中重置或清除间谍?【英文标题】:How to reset or clear a spy in Jest? 【发布时间】:2019-04-20 09:09:16 【问题描述】:

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

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

例如,如何使'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
  )
)

【问题讨论】:

【参考方案1】:

Jest 间谍具有与模拟相同的 API。模拟的文档是here,并指定了一个方法mockClear

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

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

(强调我自己的)

所以我们可以使用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
  )
)

Here is an example in CodeSandbox.

【讨论】:

可能想要更新这个。截至今天,使用 Jasmine ~2.8.6 和 jest 24.0.9,这是不正确的。 Property 'mockClear' does not exist on type 'Spy'. @Bardicer 这种方法在最新的 Jest 中仍然有效,并且根据 Jest 文档是正确的。请查看我在答案末尾放置的链接,该链接演示了它在 CodeSandbox 中的工作。 ...那么...我想我只是想在开玩笑的那天让它工作。这不会是图书馆第一次决定变得困难并且无法按预期工作。【参考方案2】:

感谢@sdgluck 的回答,尽管我想在这个答案中补充一点,在我的情况下,我希望在每次测试后都有一个清晰的状态,因为我有多个测试相同的间谍。因此,我没有在之前的测试中调用 mockClear(),而是将其移至 afterEach()(或者您可以将其与 beforeEach 一起使用),如下所示:

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

最后,我的测试工作正常,没有从之前的测试中调用间谍。

【讨论】:

还有jest.restoreAllMocks();,如果你想将模拟函数恢复到原来的实现! 您还可以将 restoreMocks: true 添加到您的 Jest 配置中,以便在每次测试后自动调用 restoreAllMocks()。就个人而言,我没有理由让模拟在任何两个测试之间持续存在,所以我喜欢在每个测试之间盲目地重置它们,而不必将其作为清理项目写在 afterEach() 块中。 您也可以在同一测试套件中的两个断言之间调用jest.clearAllMocks();。这对于您决定将单个方法的所有测试分组到一个“测试套件”下的情况很有用,但您希望断言不记住它们以前的值。 你可以简单地使用afterEach(jest.clearAllMocks)【参考方案3】:

进一步迭代@ghiscoding 的答案,您可以在Jest 配置中指定clearMocks,相当于在每次测试之间调用jest.clearAllMocks()


...
    clearMocks: true,
...

请参阅文档here。

【讨论】:

【参考方案4】:

如果您想恢复之前添加到 spy 的方法的原始行为,可以使用 mockRestore 方法。

查看下面的示例:

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 中重置或清除间谍?的主要内容,如果未能解决你的问题,请参考以下文章

如何在每次测试之前重置或清除 ApolloProvider 的 useQuery 模拟?

用 Jest 重置单个模块

如何在每次测试之前重置 Jest 模拟函数调用计数

如何使用 Jest 监视方法调用?

如何清除 Jest 模拟实现以进行下一次测试?

使用 MSW 和 Jest 时如何在请求之间的测试中清除 RTK 查询缓存?