How it is supposed to work with unit test?
See original GitHub issueHello there, I would like to test my controller (routing-controllers) but i don’t really know how to. Typedi is supposed to work like Angular2+ inject or similar. But when i use Container.set to override my model’s method used by the controller it’s seems to be broken. I need some hint to know how to do that. I think i do not test my controller like expected or maybe i don’t really understand Typedi Container and @Service injection implementation. It’s supposed to be usefull to avoid to mock db connection.
Thx a lot.
My spec
import 'reflect-metadata';
import { Application } from 'express';
import request from 'supertest';
import { createExpressServer, useContainer as useContainerRouting } from 'routing-controllers';
import { Container } from 'typedi';
import { ExampleController } from '../controllers/example.controller';
import { ExampleRepository } from '../repositories/example.repository';
import { ExampleModel } from '../models/example.model';
describe('GET', () => {
let app: Application | null;
beforeEach((_done: jest.DoneCallback) => {
useContainerRouting(Container);
});
afterEach((_done: jest.DoneCallback) => {
Container.reset();
app = null;
});
it('should call model with proper id and returns model response', async () => {
const EXAMPLE_ID_TEST: number = 1;
app = createExpressServer({
cors: true,
controllers: [
ExampleController
]
});
@Service()
class TestModel {
public getExampleById: any = jest.fn().mockImplementation((_id: number) => new Promise((resolve: any) => resolve({})));
}
Container.set(ExampleModel, new TestModel());
const res: request.Response = await request(app).get(`/example/${EXAMPLE_ID_TEST}`);
expect(res.body).toEqual({});
});
My controller
import { ExampleModel } from '../models/example.model';
import { TableTest } from '../entities/tabletest.entity';
import { JsonController, Get } from 'routing-controllers';
@JsonController('/example')
export class ExampleController {
constructor(
private readonly model: ExampleModel) {
}
@Get('/:id')
public async getExample(@Param('id') id: number): Promise<TableTest> {
return this.model.getExampleById(id);
}
}
My Model
import { TableTest } from '../entities/tabletest.entity';
import { Service } from 'typedi';
import { OrmRepository } from 'typeorm-typedi-extensions';
import { NotFoundError } from 'routing-controllers';
import { ExampleRepository } from '../repositories/example.repository';
@Service()
export class ExampleModel {
constructor(
@OrmRepository()
private readonly repository: ExampleRepository) {
}
public async getExampleById(id: number): Promise<TableTest> {
const example: TableTest | undefined = await this.repository.findOneById(id);
if (example === undefined) {
throw new NotFoundError(`Example ${id} not found`);
}
return example;
}
}
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (2 by maintainers)
Top Results From Across the Web
Unit Testing Tutorial – What is, Types & Test Example - Guru99
Unit testing allows the programmer to refactor code at a later date, and make sure the module still works correctly (i.e. Regression testing)....
Read more >Unit Testing Tutorial: 6 Best Practices to Get Up To Speed
Unit Testing Best Practices · 1. Arrange, Act, Assert · 2. One Assert Per Test Method · 3. Avoid Test Interdependence · 4....
Read more >What is unit testing and how do you do it? [duplicate]
Unit testing simply verifies that individual units of code (mostly functions) work as expected. Usually you write the test cases yourself, ...
Read more >What Is Unit Testing? - SmartBear
Unit Testing is the process of checking small pieces of code to deliver information early and often, speeding your testing strategies, and reducing...
Read more >What is Unit Testing? Definition from WhatIs.com - TechTarget
Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

General rule of thumb - keep it simple, stupid! 😉
Constructor injection in controllers is the best because it’s DI framework agnostic - you can just create the instance of the class and provide your mocks by yourself:
So you make unit test of your controller methods like they would be the services, not connected to http (thanks to routing-controllers decorators). You check all the code flow in unit tests.
Then, you can make integration test. They check if the http server really works and return correct response:
In integration test you can’t mock your code parts like services, etc. You need to check if all of your apps parts are working together. You check only the one good scenario that use all of the apps parts.
The only thing you should do is to to connect to local testing database, seed it with test data and maybe restore after each test that modified it. Mocks are allowed only to 3rd-party services like mail or Amazon S3 and I could be easily done with
container.setor at the environment level (proxy server?).So, @gmongin, don’t try to mock all the world when you are making http request to your app because you will test your mocks, not the real code 😆
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.