如何正确地让 mock 在 Jest 中抛出错误?
How to properly make mock throw an error in Jest?
我正在使用 Jest 测试我的 GraphQL api。
我正在为每个 query/mutation
使用单独的测试服
我有 2 个测试(每个都在单独的测试套件中),我模拟了一个用于突变的函数(即 Meteor 的 callMethod
)。
it('should throw error if email not found', async () => {
callMethod
.mockReturnValue(new Error('User not found [403]'))
.mockName('callMethod');
const query = FORGOT_PASSWORD_MUTATION;
const params = { email: 'user@example.com' };
const result = await simulateQuery({ query, params });
console.log(result);
// test logic
expect(callMethod).toBeCalledWith({}, 'forgotPassword', {
email: 'user@example.com',
});
// test resolvers
});
当我 console.log(result)
我得到
{ data: { forgotPassword: true } }
这种行为不是我想要的,因为在 .mockReturnValue
中我抛出了一个错误,因此期望 result
有一个错误对象
然而,在这个测试之前,另一个是运行
it('should throw an error if wrong credentials were provided', async () => {
callMethod
.mockReturnValue(new Error('cannot login'))
.mockName('callMethod');
运行正常,报错
我想问题是测试完成后 mock 没有被重置。
在我的 jest.conf.js
我有 clearMocks: true
每个测试套件都在一个单独的文件中,我在测试之前模拟函数是这样的:
import simulateQuery from '../../../helpers/simulate-query';
import callMethod from '../../../../imports/api/users/functions/auth/helpers/call-accounts-method';
import LOGIN_WITH_PASSWORD_MUTATION from './mutations/login-with-password';
jest.mock(
'../../../../imports/api/users/functions/auth/helpers/call-accounts-method'
);
describe('loginWithPassword mutation', function() {
...
更新
当我用 .mockImplementation
替换 .mockReturnValue
时,一切都按预期进行:
callMethod.mockImplementation(() => {
throw new Error('User not found');
});
但这并不能解释为什么在另一个测试中 .mockReturnValue
工作正常...
将 .mockReturnValue
更改为 .mockImplementation
:
yourMockInstance.mockImplementation(() => {
throw new Error();
});
万一你想断言
test('the fetch fails with an error', () => {
return expect(fetchData()).rejects.toMatch('error');
});
如果这是一个承诺,你也可以 .rejects www.jestjs.io/docs/en/asynchronous#resolves--rejects
对于Angular+是:
import { throwError } from 'rxjs';
yourMockInstance.mockImplementation(() => {
return throwError(new Error('my error message'));
});
对于 promise,可以使用 https://jestjs.io/docs/mock-function-api#mockfnmockrejectedvaluevalue
test('async test', async () => {
const asyncMock = jest.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"
});
为了测试是否抛出错误,可以使用https://eloquentcode.com/expect-a-function-to-throw-an-exception-in-jest
const func = () => {
throw new Error('my error')
}
it('should throw an error', () => {
expect(func).toThrow()
})
我正在使用 Jest 测试我的 GraphQL api。
我正在为每个 query/mutation
使用单独的测试服我有 2 个测试(每个都在单独的测试套件中),我模拟了一个用于突变的函数(即 Meteor 的 callMethod
)。
it('should throw error if email not found', async () => {
callMethod
.mockReturnValue(new Error('User not found [403]'))
.mockName('callMethod');
const query = FORGOT_PASSWORD_MUTATION;
const params = { email: 'user@example.com' };
const result = await simulateQuery({ query, params });
console.log(result);
// test logic
expect(callMethod).toBeCalledWith({}, 'forgotPassword', {
email: 'user@example.com',
});
// test resolvers
});
当我 console.log(result)
我得到
{ data: { forgotPassword: true } }
这种行为不是我想要的,因为在 .mockReturnValue
中我抛出了一个错误,因此期望 result
有一个错误对象
然而,在这个测试之前,另一个是运行
it('should throw an error if wrong credentials were provided', async () => {
callMethod
.mockReturnValue(new Error('cannot login'))
.mockName('callMethod');
运行正常,报错
我想问题是测试完成后 mock 没有被重置。
在我的 jest.conf.js
我有 clearMocks: true
每个测试套件都在一个单独的文件中,我在测试之前模拟函数是这样的:
import simulateQuery from '../../../helpers/simulate-query';
import callMethod from '../../../../imports/api/users/functions/auth/helpers/call-accounts-method';
import LOGIN_WITH_PASSWORD_MUTATION from './mutations/login-with-password';
jest.mock(
'../../../../imports/api/users/functions/auth/helpers/call-accounts-method'
);
describe('loginWithPassword mutation', function() {
...
更新
当我用 .mockImplementation
替换 .mockReturnValue
时,一切都按预期进行:
callMethod.mockImplementation(() => {
throw new Error('User not found');
});
但这并不能解释为什么在另一个测试中 .mockReturnValue
工作正常...
将 .mockReturnValue
更改为 .mockImplementation
:
yourMockInstance.mockImplementation(() => {
throw new Error();
});
万一你想断言
test('the fetch fails with an error', () => {
return expect(fetchData()).rejects.toMatch('error');
});
如果这是一个承诺,你也可以 .rejects www.jestjs.io/docs/en/asynchronous#resolves--rejects
对于Angular+是:
import { throwError } from 'rxjs';
yourMockInstance.mockImplementation(() => {
return throwError(new Error('my error message'));
});
对于 promise,可以使用 https://jestjs.io/docs/mock-function-api#mockfnmockrejectedvaluevalue
test('async test', async () => {
const asyncMock = jest.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"
});
为了测试是否抛出错误,可以使用https://eloquentcode.com/expect-a-function-to-throw-an-exception-in-jest
const func = () => {
throw new Error('my error')
}
it('should throw an error', () => {
expect(func).toThrow()
})