在jest中对抛出的错误对象进行Assert

muk1a3rh  于 2023-05-15  发布在  Jest
关注(0)|答案(7)|浏览(221)

我有一个抛出一个对象的函数,我怎么能Assert在jest中抛出的是正确的对象呢?

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

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

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

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

https://repl.it/repls/FrayedViolentBoa

ui7jx7zq

ui7jx7zq1#

如果您正在寻找测试自定义错误的内容(我认为这是您正在尝试做的)。您可以捕获错误,然后执行Assert。

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

svmlkihl2#

您需要抛出一个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));
});
zour9fqk

zour9fqk4#

如果目标是检查错误的部分内容,我们可以使用Jest expect.objectContaining来帮助我们保持代码简单,并检查作为错误返回的对象有效负载:

const invalidJob = () => {
  throw {
    type: '/errors/invalid-job',
    message: 'This job is invalid',
  };
};
expect(() => invalidJob()).toThrowError(
  expect.objectContaining({
    type: '/errors/invalid-job',
  })
);

也可用于嵌套对象:

const invalidJob = () => {
  throw {
    response: {
      type: '/errors/invalid-job',
      message: 'This job is invalid',
    },
    status: 400
  };
};
expect(() => invalidJob()).toThrowError(
  expect.objectContaining({
    status: 400,
    response: expect.objectContaining({
      type: '/errors/invalid-job'
    })
  })
);
avwztpqn

avwztpqn5#

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

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

xlpyo6sf6#

当我需要测试一个自定义错误(Error的子类)时,我使用以下方法:

export class CustomError extends Error {
  constructor(public code: string, public data: any) {
    super(`Custom Error`);
  }
}

export async function method(): Promise<void> {
  throw new CustomError('ABC001', { field: 'X' });
}

// test:

it('should throw a CustomError for field X', () => {
  expect.assertions(1); // Expects for an error
  return method().catch(e => {
    expect(Object.assign({}, e)).toStrictEqual({
      code: 'ABC001',
      data: { field: 'X' }
    });
  });
});
2nc8po8w

2nc8po8w7#

我想提出一个在Jest中使用rejects对象的解决方案。假设fn是一个syncronous函数,你可以像这样编写测试:

it('should throw', async () => {
  const errorObj = {
    myError: {
      name: 'myError',
      desc: 'myDescription'
    }
  };

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

  await expect(async () => fn()).rejects.toMatchObject(errorObj);
});

使用这些解决方案,可以使fn()执行异步。这允许我们使用rejects对象,该对象将包含抛出异常的对象。这样你就可以使用toMatchObject()来检查抛出的物体的形状。

相关问题