Внедрение Mocks в приложение NestJS для тестирования контрактов

Проблема

Я ищу способ запустить приложение NestJS с поддельными поставщиками. Это необходимо для тестирования контракта с провайдером, потому что услугу нужно запускать изолированно. При использовании библиотеки Pact при тестировании провайдера предполагается, что сервис провайдера уже запущен. Он должен иметь возможность отправлять HTTP-запросы к фактическому серверу (при необходимости с фиксацией некоторых зависимостей). PactJS

Текущее исследование

Я просмотрел документацию по NestJS, и ближайшее решение, которое я могу найти, вставлено ниже. Насколько я могу судить, это решение сообщает модулю о необходимости замены любого поставщика с именем CatsService на catsService. Теоретически это сработает для целей тестирования контрактов с поставщиками, но я не думаю, что это позволяет запускать все приложение, только модуль. В документации нет упоминания о возможности запускать приложение на определенном порту с помощью модуля тестирования. Я попытался вызвать app.listen для возвращенного объекта приложения, но он не смог достичь точки останова, установленной сразу после вызова.

import * as request from "supertest";
import { Test } from "@nestjs/testing";
import { CatsModule } from "../../src/cats/cats.module";
import { CatsService } from "../../src/cats/cats.service";
import { INestApplication } from "@nestjs/common";

describe("Cats", () => {
  let app: INestApplication;
  let catsService = { findAll: () => ["test"] };

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [CatsModule]
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = module.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get("/cats")
      .expect(200)
      .expect({
        data: catsService.findAll()
      });
  });

  afterAll(async () => {
    await app.close();
  });
});

Пример Java

Используя Spring класс конфигурации, макеты можно внедрять в приложение при работе с профилем «контракт-тест».

@Profile({"contract-test"})
@Configuration
public class ContractTestConfig {

  @Bean
  @Primary
  public SomeRepository getSomeRepository() {
    return mock(SomeRepository.class);
  }

  @Bean
  @Primary
  public SomeService getSomeService() {
    return mock(SomeService.class);
  }
} 
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
7
0
5 029
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обновлять

Начиная с версии 4.4 вы также можете использовать listen, поскольку теперь он также возвращает Promise.


Вы должны использовать метод listenAsync вместо listen, чтобы вы могли использовать его с await:

beforeAll(async () => {
  const moduleFixture = await Test.createTestingModule({
    imports: [AppModule],
  })
    .overrideProvider(AppService).useValue({ root: () => 'Hello Test!' })
    .compile();

  app = moduleFixture.createNestApplication();
  await app.init();
  await app.listenAsync(3000);
        ^^^^^^^^^^^^^^^^^^^^^
});

Тогда вы можете делать реальные HTTP-запросы вместо того, чтобы полагаться на супертесты. (В этом примере я использую стандартную http-библиотеку nodejs.)

import * as http from 'http';

// ...

it('/GET /', done => {
  http.get('http://localhost:3000/root', res => {
    let data = '';
    res.on('data', chunk => data = data + chunk);
    res.on('end', () => {
      expect(data).toEqual('Hello Test!');
      expect(res.statusCode).toBe(200);
      done();
    });
  });
});

Не забудьте закрыть приложение, иначе ваш тест будет работать до тех пор, пока не будет закрыт вручную.

afterAll(() => app.close());

Я только что понял, что часть про listenAsync устарела, а остальное у меня работает. Я также могу запросить сайт в браузере во время выполнения теста. Я использую версию 5.3.5

Kim Kern 09.11.2018 21:19

Большое спасибо!

Mojo982 09.11.2018 22:33

Другие вопросы по теме