Ожидается конкретная ошибка при написании юнит-тестов в шутку - PullRequest
0 голосов
/ 18 мая 2019

Я использую nestjs (6.5.0) и jest (24.8) и у меня есть метод, который выдает ошибку:

  public async doSomething(): Promise<{ data: string, error?: string }> {
    throw new BadRequestException({ data: '', error: 'foo' });
  }

Как мне написать модульный тест, который проверяет, что мы получаем ожидаемое исключение с ожидаемыми данными? Очевидное решение:

it('test', async () => {
  expect(await userController.doSomething())
    .rejects.toThrowError(new BadRequestException({ data: '', error: 'foo'});
});

но это не работает, потому что new BadRequestException() создает объект с другим стеком вызовов. Как я могу это проверить?

Ответы [ 2 ]

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

Отвечая на мой собственный вопрос:

С помощью специального сопоставителя (см. Ниже) тест можно записать в виде:

it('test', async () => {
  await expect(userController.doSomething()).rejects.toContainException(
    new BadRequestException({ data: '', error: 'foo' }),
  );
});

Пользовательского сопоставителя:

import { HttpException } from '@nestjs/common';

// ensure this is parsed as a module.
export {};

// https://stackoverflow.com/questions/43667085/extending-third-party-module-that-is-globally-exposed

declare global {
  namespace jest {
    interface Matchers<R> {
      toContainException: (expected: R | any) => {};
    }
  }
}

// this will extend the expect with a custom matcher
expect.extend({
  toContainException<T extends HttpException>(received: T, expected: T) {
    const success =
      this.equals(received.message, expected.message) &&
      this.equals(received.getStatus(), expected.getStatus());

    const not = success ? ' not' : '';
    return {
      message: () =>
        `expected Exception ${received.name}${not} to be ${expected.name}` +
        '\n\n' +
        `Expected: ${this.utils.printExpected(expected.message)}, ` +
        `status: ${this.utils.printExpected(expected.getStatus())} \n` +
        `Received: ${this.utils.printReceived(received.message)}, ` +
        `status: ${this.utils.printReceived(received.getStatus())}`,
      pass: success,
    };
  },
});
0 голосов
/ 18 мая 2019

По сравнению с примерами из документации jest здесь может быть две проблемы.

  • await должно быть вне аргумента expect
  • rejects означает, что была выдана ошибка, поэтому вы проверяете равенство

Что-то вроде:

it('test', async () => {
  await expect(userController.doSomething())
    .rejects.toEqual(new BadRequestException({ data: '', error: 'foo'});
});
...