Issue
I'm looking for a way to bring up a NestJS application with mocked providers. This is necessary for provider contract tests because a service needs to be brought up in isolation. Using the Pact library, testing the provider assumes that the provider service is already running. It needs to be able to make HTTP requests against the actual server (with some dependencies mocked if necessary). PactJS
Current Research
I've looked into the docs for NestJS and the closest solution I can find is pasted below. From what I can tell, this solution tells the module to replace any provider called CatsService
with catsService
. This theoretically would work for provider contract testing purposes, but I don't think this allows for the entire app to be brought up, just a module. There is no mention in the docs for being able to bring up the app on a specific port using the testing module. I've tried to call app.listen
on the returned app object and it fails to hit a breakpoint placed right after the call.
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 Example
Using Spring a configuration class, mocks can be injected into the app when running with the "contract-test" profile.
@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);
}
}