如何使用Jest成功模拟并捕获错误?

时间:2019-05-15 18:22:38

标签: javascript node.js unit-testing jestjs

几天来我一直在尝试创建特定的测试,我一直很努力,希望能对我做错的事情有所了解。

我正在尝试模拟Array过滤器函数以引发错误。

userHelper.js

//filter users by email ending
const filterUsersByEmailDomain = (usersArray, emailEnding) => {
    try {
        let bizUsers = usersArray.filter(user => {
            return user.email.endsWith(emailEnding);
        });
        return bizUsers;
    } catch (err) {
        console.log('error filtering users. Throwing error.');
        throw err;
    }
}

userHelper.test.js:

it('should throw', () => {
        const user1 = {id: 1, email: 'tyler@tyler.com'};
        const user2 = {id: 2, email: 'tevin@tevin.biz'};
        const userArray = [user1, user2];
        const domainEnding = '.biz';

        Array.prototype.filter = jest.fn().mockImplementation(() => {throw new Error()});

        expect(() => {usersHelper.filterUsersByEmailDomain(userArray, domainEnding)}).toThrow();
    });

据我所知,该错误正在抛出,但未成功捕获。我也尝试过在try catch块中对usersHelper.filterUsersByEmailDomain()进行调用,就像我看到其他人所做的一样,但也没有成功。预先感谢!

编辑: 这是在我的项目中本地运行此测试设置时收到的错误。

  ● Testing the usersHelper module › should throw



      56 |         const domainEnding = '.biz';
      57 | 
    > 58 |         Array.prototype.filter = jest.fn().mockImplementation(() => {throw new Error()});
         |                                                                            ^
      59 | 
      60 |         expect(() => {usersHelper.filterUsersByEmailDomain(userArray, domainEnding)}).toThrow();
      61 |     });

      at Array.filter.jest.fn.mockImplementation (utils/__tests__/usersHelper.test.js:58:76)
      at _objectSpread (node_modules/expect/build/index.js:60:46)
      at Object.throwingMatcher [as toThrow] (node_modules/expect/build/index.js:264:19)
      at Object.toThrow (utils/__tests__/usersHelper.test.js:60:87)

(node:32672) UnhandledPromiseRejectionWarning: Error
(node:32672) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .c
atch(). (rejection id: 2)
(node:32672) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

2 个答案:

答案 0 :(得分:1)

$(".other").click(function() { //my action }); 是一个非常低级的函数,对其进行嘲笑以引发错误可能会导致测试无法正常运行。

进行以下简单测试:

Array.prototype.filter

...效果很好...

...但是模拟it('should throw', () => { expect(() => { throw new Error() }).toThrow(); // Success! }); 会引发错误,但失败:

Array.prototype.filter

相反,只需在数组本身上模拟it('should throw', () => { Array.prototype.filter = jest.fn(() => { throw new Error() }); expect(() => { throw new Error() }).toThrow(); // Fail! });

filter

JavaScript在检查对象原型之前会先在对象本身上查找属性,以便it('should throw', () => { const user1 = { id: 1, email: 'tyler@tyler.com' }; const user2 = { id: 2, email: 'tevin@tevin.biz' }; const userArray = [user1, user2]; const domainEnding = '.biz'; userArray.filter = () => { throw new Error() }; // <= mock filter on userArray expect(() => { usersHelper.filterUsersByEmailDomain(userArray, domainEnding) }).toThrow(); // Success! }); 上的模拟filteruserArray中被调用,并且测试按预期通过。

答案 1 :(得分:0)

您想将toThrow()放在执行测试功能之前,用Jest'toX'表示必须事先设置,例如:toBeCalled()。这就是toHaveBeenCalled()存在的原因,因为这种形式允许断言在代码运行后发生。