【问题标题】:Jest: Does not allow mocked method to be overwritten开玩笑:不允许覆盖模拟方法
【发布时间】:2020-07-03 15:28:29
【问题描述】:

给定以下测试代码:

import { MyParentClass } from "MyParentClass";
import { MyClass } from "MyClass";

MyClass.prototype.post = jest.fn(() => Promise.resolve({token: '12345'}));

it('first test: this test will be successful tested ✓', async() => {
    const myParentClass = new MyParentClass();
    await expect(myParentClass.run()).toEqual({token: '12345'});
})

it('second test: this test will fail ×', async () => {
    MyClass.prototype.post = jest.fn(() => Promise.reject({message: 'An error ocurred'}));
    const myParentClass = new MyParentClass();
    await expect(myParentClass.run()).rejects.toEqual({message: 'success'});
})

run”方法在内部使用了“MyClass”类及其“post”方法。当我运行这样的代码时,对于我的第二次测试,我收到如下消息:

"Received promise resolved instead of rejected"

我明白当“post”方法的答案被全局定义时,它总是取那个值,但我也明白在第二个测试I am overwriting那个方法的行为,为什么不你会考虑吗?

我知道我也可以使用jest.doMock,但我不太了解文档,有人可以帮我理解它以将其应用于我的示例吗?

【问题讨论】:

    标签: javascript unit-testing testing mocking jestjs


    【解决方案1】:

    使用asyncFn 这样可以解决问题,并通过按时间顺序读取来简化测试。

    import asyncFn from '@asyncFn/jest';
    
    describe('myParentClass', () => {
      let parentClass;
      let runPromise;
    
      beforeEach(() => {
        parentClass = new MyParentClass();
        parentClass.post = asyncFn();
        runPromise = myParentClass.run();
      });      
    
      it('first test: this test will be successful tested ✓', () => {
        parentClass.post.resolve({ token: '12345' });
    
        return expect(runPromise).resolves.toEqual({ token: '12345' });
      })
    
      it('second test: this test will fail ×', () => {
        parentClass.post.reject({ message: 'An error occured'} );
    
        return expect(runPromise).rejects.toEqual({ message: 'An error occured' });
      });
    });
    

    【讨论】:

      【解决方案2】:

      您可以使用mockImplementationOncemockReturnValueOnce,因为您已经将post 转换为一个笑话模拟函数。所以你可以在第二次测试中做这样的事情:

      it('second test: this test will fail ×', async () => {
        MyClass.prototype.post.mockReturnValueOnce(Promise.reject({message: 'An error ocurred'}));
        const myParentClass = new MyParentClass();
        await expect(myParentClass.run()).rejects.toEqual({message: 'An error ocurred'});
      })
      

      【讨论】:

        猜你喜欢
        • 2021-12-09
        • 2019-03-23
        • 2018-10-29
        • 2021-06-26
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多