简体   繁体   English

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

[英]Why is the spyOn function in the test not working with sendGrid?

I am setting up a graphql server with graphql-yoga and `prisma using Typescript.我正在使用graphql-yoga设置带有graphql-yoga和 `prisma 的 graphql 服务器。 When a user signs up, an email with a link for validation will be sent to the given email address.当用户注册时,带有验证链接的电子邮件将发送到给定的电子邮件地址。 Everything is working fine, but i want to write a test for the mutation before refactoring the functionality, which checks if the 'send' function of SendGrid hast been called.一切正常,但我想在重构功能之前为突变编写一个测试,以检查是否已调用 SendGrid 的“发送”函数。

I tried spying on the function with jest.spyOn , but all I get is an error, that comes from not providing an API key for SendGrid in the tesing environment.我尝试使用jest.spyOn监视该函数,但我得到的只是一个错误,这是由于未在测试环境中为 SendGrid 提供 API 密钥。

I have used spyOn before, and it worked, though this is the first time I am using jest with Typescript.我以前使用过 spyOn,它奏效了,尽管这是我第一次在 Typescript 中使用 jest。

SignUp Mutation注册突变

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

Trying spyOn尝试间谍

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

Running the test gives me:运行测试给了我:

Error: GraphQL error: Unauthorized错误:GraphQL 错误:未经授权

Commenting out the function call of send in the mutation and running the test gives me:注释掉变异中的 send 函数调用并运行测试给了我:

Error: expect(spy).toHaveBeenCalled()错误:expect(spy).toHaveBeenCalled()

Expected spy to have been called, but it was not called.预期 spy 已被调用,但未调用。

You don't mock @sendgrid/mail module in a correct way.您没有以正确的方式模拟@sendgrid/mail模块。 That's why the error happened.这就是错误发生的原因。 Here is the solution without using GraphQL test client.这是不使用GraphQL测试客户端的解决方案。 But you can use GraphQL test client to test your GraphQL resolver and GraphQL Schema after you mock @sendgrid/mail module correctly.但是您可以在正确模拟@sendgrid/mail模块后使用GraphQL测试客户端来测试您的GraphQL解析器和GraphQL架构。

mutations.ts : 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 : 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`
      });
    });
  });
});

Unit test result with 100% coverage: 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

Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56379585这是完整的演示: https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56379585

I have the exact same problem but without Graphql, for me it's a simple function: 我有完全相同的问题,但没有Graphql,对我来说这是一个简单的函数:

const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

const simplemail = () => {
  const msg = {
    to: 'receiver@mail.com',
    from: 'sender@test.com',
    subject: 'TEST Sendgrid with SendGrid is Fun',
    text: 'and easy to do anywhere, even with Node.js',
    html: '<strong>and easy to do anywhere, even with Node.js</strong>',
    mail_settings: {
      sandbox_mode: {
        enable: true,
      },
    },
  };
  (async () => {
    try {
      console.log(await sgMail.send(msg));
    } catch (err) {
      console.error(err.toString());
    }
  })();
};

export default simplemail;

i would like to test it with jest and mock sendgrid it but how ? 我想用玩笑和模拟sendgrid测试它,但如何?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM