Как успешно издеваться и ловить ошибку с помощью Jest? - PullRequest
1 голос
/ 15 мая 2019

Я застрял, пытаясь создать определенный тест в течение нескольких дней, и был бы признателен за понимание того, что я могу делать неправильно.

Я пытаюсь смоделировать функцию фильтра массива, чтобы выдать ошибку.

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();
    });

Из того, что я могу сказать, ошибка выдается, но успешно не перехватывается. Я также попытался сделать вызов для usersHelper.filterUsersByEmailDomain () в блоке try catch, как я видел, как это делают другие, но также безуспешно. Заранее спасибо!

Edit: Вот ошибка, которую я получаю при локальном запуске этой тестовой настройки в моем проекте.

  ● 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 ]

1 голос
/ 20 мая 2019

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 насам массив:

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!
});

JavaScript проверяет свойство в самом объекте перед проверкой его прототипа, поэтому макет filter в userArray вызывается в filterUsersByEmailDomain и тест проходит, как и ожидалось.

0 голосов
/ 18 мая 2019

Вы хотите поместить свой toThrow() перед выполнением протестированной функции, в Jest 'toX' означает, что он должен быть настроен заранее, например: toBeCalled(). Вот почему существует toHaveBeenCalled(), так как эта форма позволяет утверждению произойти после выполнения кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...