在玩笑中针对抛出的错误对象断言

IT技术 javascript reactjs jestjs
2021-05-14 14:58:37

我有一个抛出对象的函数,我如何断言正确的对象是开玩笑的?

it('should throw', () => {

  const errorObj = {
    myError: {
      name: 'myError',
      desc: 'myDescription'
    }
  };

  const fn = () => {
    throw errorObj;
  }

  expect(() => fn()).toThrowError(errorObj);
});

https://repl.it/repls/FrayedViolentBoa

4个回答

如果您想测试自定义错误的内容(我认为这就是您想要做的)。您可以捕获错误,然后执行断言。

it('should throw', () => {
 let thrownError;

 try {
   fn();
 }
 catch(error) {
  thrownError = error;
 }

 expect(thrownError).toEqual(expectedErrorObj);
});

正如 Dez 所建议的,如果您不抛出 javascript Error 对象的实例,则 toThrowError 函数将不起作用。但是,您可以通过装饰错误对象的实例来创建自定义错误。

例如

let myError = new Error('some message');
myError.data = { name: 'myError',
                 desc: 'myDescription' };
throw myError;

然后,一旦您在测试中发现了错误,您就可以测试错误的自定义内容。

expect(thrownError.data).toEqual({ name: 'myError',
                                   desc: 'myDescription' });

您需要抛出一个 JavascriptError对象,因此 JesttoThrowError方法会识别出已抛出错误。此外,toThrowError看起来与抛出的错误消息相匹配,或者如果您只是通过检查是否已抛出错误.toThrowError()

it('should throw', () => {

  const errorObj = {
    myError: {
      name: 'myError',
      desc: 'myDescription'
    }
  };

  const fn = () => {
    throw new Error(errorObj.myError.desc);
  }

  expect(() => fn()).toThrowError("myDescription");
});

如果您想检查整个对象是否按原样传递,您需要像这样检查它:

it('should throw', () => {

  const errorObj = {
    myError: {
      name: 'myError',
      desc: 'myDescription'
    }
  };

  const fn = () => {
    throw errorObj;
  }

  expect(() => fn()).toThrowError(new Error(errorObj));
});

这是开玩笑的已知问题,请参阅https://github.com/facebook/jest/issues/8140

同时,这是我的解决方法 - https://github.com/DanielHreben/jest-matcher-specific-error

您可以添加自定义匹配器。

1. 自定义匹配器

import { CsrfError } from '../src/shield';

declare global {
  namespace jest {
    interface Matchers<R> {
      toThrowCsrfError(expected: {
        statusCode: number;
        message: string;
      }): CustomMatcherResult;
    }
  }
}

const mismatchResult = (message: string) => ({
  pass: false,
  message: () => message,
});

expect.extend({
  toThrowCsrfError(received, expected): jest.CustomMatcherResult {
    try {
      received();
    } catch (error) {
      const isCsrfError = error instanceof CsrfError;
      if (!isCsrfError) {
        return mismatchResult('Not an CsrfError Error');
      }

      if (error.message !== expected.message) {
        return mismatchResult(
          `Recieved Message "${error.message}" different from expected "${expected.message}"`
        );
      }

      if (error.statusCode !== expected.statusCode) {
        return mismatchResult(
          `Recieved statusCode "${error.statusCode}" different from expected "${expected.statusCode}"`
        );
      }

      return {
        pass: true,
        message: () => ``,
      };
    }

    return {
      pass: false,
      message: () => `Expected to throw, but didn't`,
    };
  },
});

2. 添加到 setupFilesAfterEnv

在您jest.config将上面的文件添加到您的setupFilesAfterEnv列表中,例如:

const config = {
  setupFilesAfterEnv: ['./test/matchers.ts'],
};

module.exports = config;

3. 打电话

  expect(() => {
    shield({ pathname: 'https://example.com/' });
  }).toThrowCsrfError({ statusCode: 401, message: 'No CSRF cookie.' });