为什么测试中的 spyOn 函数不能与 sendGrid 一起使用?



我正在使用Typescript设置一个带有graphql-yoga和'prisma的graphql服务器。当用户注册时,一封带有验证链接的电子邮件将发送到给定的电子邮件地址。 一切正常,但我想在重构功能之前为突变编写一个测试,以检查是否已调用 SendGrid 的"发送"函数。

我尝试用jest.spyOn监视该功能,但我得到的只是一个错误,该错误来自未在测试环境中为 SendGrid 提供 API 密钥。

我以前使用过spyOn,它奏效了,尽管这是我第一次在打字稿中使用jest。

注册突变

import * as sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.MAIL_API_KEY);
export const Mutation = {
async signUpUser(parent, { data }, { prisma }, info) {
[...]
const emailData = {
from: 'test@test.de',
to: `${user.email}`,
subject: 'Account validation',
text: `validation Id: ${registration.id}`
};
await sgMail.send(emailData);
return user;
}
}

尝试间谍

import * as sgMail from '@sendgrid/mail';
const signUpUserMutation = gql`
mutation($data: ValidationInput) {
signUpUser (data: $data) {
id
email
}
}
`;
it('should send a registration email, with a link, containing the id of the registration', async () => {
spyOn(sgMail, "send").and.returnValue(Promise.resolve('Success'));
const variables = {
data: {
email: "test@test.de",
password: "anyPassword"
}
};
await client.mutate({ mutation: signUpUserMutation, variables});
expect(sgMail.send).toHaveBeenCalled();
});

运行测试给我:

错误:GraphQL 错误:未经授权

注释掉突变中发送的函数调用并运行测试给我:

错误: expect(spy).toHaveBeenCalled()

预计间谍已被召唤,但没有被召唤。

你不会以正确的方式模拟@sendgrid/mail模块。这就是发生错误的原因。这是不使用测试客户端的解决方案GraphQL。但是,您可以使用测试客户端GraphQL测试GraphQL解析程序,并在正确模拟模块后GraphQL@sendgrid/mail架构。

mutations.ts

import * as sgMail from '@sendgrid/mail';
sgMail.setApiKey(process.env.MAIL_API_KEY || '');
export const Mutation = {
async signUpUser(parent, { data }, { prisma }, info) {
const user = { email: 'example@gmail.com' };
const registration = { id: '1' };
const emailData = {
from: 'test@test.de',
to: `${user.email}`,
subject: 'Account validation',
text: `validation Id: ${registration.id}`
};
await sgMail.send(emailData);
return user;
}
};

mutations.spec.ts

import { Mutation } from './mutations';
import * as sgMail from '@sendgrid/mail';
import { RequestResponse } from 'request';
jest.mock('@sendgrid/mail', () => {
return {
setApiKey: jest.fn(),
send: jest.fn()
};
});
describe('Mutation', () => {
describe('#signUpUser', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('should send a registration email, with a link, containing the id of the registration', async () => {
(sgMail.send as jest.MockedFunction<typeof sgMail.send>).mockResolvedValueOnce([{} as RequestResponse, {}]);
const actualValue = await Mutation.signUpUser({}, { data: {} }, { prisma: {} }, {});
expect(actualValue).toEqual({ email: 'example@gmail.com' });
expect(sgMail.send).toBeCalledWith({
from: 'test@test.de',
to: 'example@gmail.com',
subject: 'Account validation',
text: `validation Id: 1`
});
});
});
});

100% 覆盖率的单元测试结果:

PASS  src/stackoverflow/56379585/mutations.spec.ts (12.419s)
Mutation
#signUpUser
✓ should send a registration email, with a link, containing the id of the registration (23ms)
--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |      100 |      100 |      100 |      100 |                   |
mutations.ts |      100 |      100 |      100 |      100 |                   |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.315s

以下是已完成的演示: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56379585

最新更新