【问题标题】:asserting against thrown error objects in jest开玩笑地断言抛出的错误对象
【发布时间】:2018-07-20 07:11:14
【问题描述】:

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

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

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

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

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

https://repl.it/repls/FrayedViolentBoa

【问题讨论】:

    标签: javascript reactjs jestjs


    【解决方案1】:

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

    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.' });
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 非常棒。好工作。希望将来可以将匹配器添加到 Jest 中。
      【解决方案3】:

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

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

      【讨论】:

      • 是的,try catch 会起作用,感觉必须引入一个变量有点啰嗦,但如果这是目前唯一的方法......很好
      • 我还要确保添加一个expert.assertions(1),以防函数不出错并防止笑话通过。
      【解决方案4】:

      您需要抛出一个 Javascript Error 对象,因此 Jest toThrowError 方法会识别出一个错误已被抛出。此外,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));
      });
      

      【讨论】:

      • 不幸的是,我无法更改来源,(因为这完全可以用 mocha、chia 和 sinon 进行测试)。如果我在一个错误对象上断言,我传递给错误对象的对象并不重要,它仍然会传递我真正想要的,例如期望(() => fn()).toThrowError(new Error({}));
      • 如果你想检查“完全匹配”,这不会正常工作,因为 toThrow/toThrowError 只检查被抛出对象的 .message 属性。
      猜你喜欢
      • 2021-07-22
      • 2020-03-11
      • 2021-07-13
      • 2018-08-14
      • 1970-01-01
      • 2018-07-15
      • 2018-09-27
      • 2018-02-14
      • 2020-07-08
      相关资源
      最近更新 更多