Почему функция spyOn в тесте не работает с sendGrid?

Я настраиваю сервер graphql с graphql-yoga и `prisma, используя Typescript. Когда пользователь регистрируется, на указанный адрес электронной почты будет отправлено электронное письмо со ссылкой для проверки. Все работает нормально, но я хочу написать тест на мутацию перед рефакторингом функциональности, который проверяет, была ли вызвана функция отправки SendGrid.

Я пробовал шпионить за функцией с помощью jest.spyOn, но все, что я получаю, - это ошибка, возникающая из-за того, что я не предоставил ключ API для SendGrid в среде тестирования.

Раньше я использовал spyOn, и он работал, хотя я впервые использую jest с Typescript.

Подписка на мутацию

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: '[email protected]',
            to: `${user.email}`,
            subject: 'Account validation',
            text: `validation Id: ${registration.id}`
        };
        await sgMail.send(emailData);

        return user;
    }
}

Попытка 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: "[email protected]",
            password: "anyPassword"
        }
    };

    await client.mutate({ mutation: signUpUserMutation, variables});
    expect(sgMail.send).toHaveBeenCalled();
});

Выполнение теста дает мне:

Ошибка: ошибка GraphQL: неавторизованный

Комментируя вызов функции send в мутации и запуск теста, я получаю:

Ошибка: ожидать (шпион) .toHaveBeenCalled ()

Ожидаемый шпион должен был быть вызван, но он не был вызван.


person lorenzbayr    schedule 30.05.2019    source источник
comment
Я не пытался выяснить, является ли это причиной проблемы, но spyOn - это недокументированная устаревшая функция из Jasmine, которая все еще работает в Jest, но, вероятно, не должна (вы можете использовать --errorOnDeprecated, чтобы выдать ошибку, если устаревшие API используются в ваши тесты) ... вместо этого используйте jest.spyOn   -  person Brian Adams    schedule 31.05.2019


Ответы (1)


Вы неправильно издеваетесь над @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: '[email protected]' };
    const registration = { id: '1' };
    const emailData = {
      from: '[email protected]',
      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: '[email protected]' });
      expect(sgMail.send).toBeCalledWith({
        from: '[email protected]',
        to: '[email protected]',
        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.

person slideshowp2    schedule 26.09.2019