bulletproof-nodejs
bulletproof-nodejs copied to clipboard
where are all the "beautiful" unit tests?
In your injector you proclaim:
`/**
- WTF is going on here?
- We are injecting the mongoose models into the DI container.
- I know this is controversial but will provide a lot of flexibility at the time
- of writing unit tests, just go and check how beautiful they are! */ `
And yet there are no tests.
I tried to create a test myself for the AuthService - SignUp. What I got so far:
import {Container} from 'typedi';
import express from 'express';
import AuthService from '../../../src/services/auth';
import loaders from '../../../src/loaders';
let db = null;
beforeAll(async (done) => {
const expressApp = express();
const {mongoConnection} = await loaders({expressApp});
db = mongoConnection;
done();
});
afterAll(async (done) => {
const UserModel = Container.get('userModel');
await UserModel.deleteMany({email: "[email protected]"});
db.connection.close(() => done());
});
describe('Auth service', () => {
describe('SignUp', () => {
test('should create user record', async () => {
const userInput = {
firstName: 'User',
lastName: 'Unit Test',
email: '[email protected]',
password: 'test',
};
const UserModel = Container.get('userModel');
const Logger = Container.get('logger');
const authService = new AuthService(UserModel, Logger);
const {user, token} = await authService.SignUp(userInput);
expect(user).toBeDefined();
expect(user._id).toBeDefined();
expect(user.firstName).toBe("User");
expect(user.lastName).toBe("Unit Test");
expect(user.email).toBe("[email protected]");
expect(user.password).not.toBeDefined();
expect(user.salt).not.toBeDefined();
expect(token).toBeDefined();
});
});
describe('SignIn', () => {
it('should be able to login', async () => {
const UserModel = Container.get('userModel');
const Logger = Container.get('logger');
const authService = new AuthService(UserModel, Logger);
const {user, token} = await authService.SignIn('[email protected]', 'test');
expect(user).toBeDefined();
expect(user._id).toBeDefined();
expect(user.firstName).toBe("User");
expect(user.lastName).toBe("Unit Test");
expect(user.email).toBe("[email protected]");
expect(user.password).not.toBeDefined();
expect(user.salt).not.toBeDefined();
expect(token).toBeDefined();
});
it('should throw an error when email was not registered yet', async () => {
const UserModel = Container.get('userModel');
const Logger = Container.get('logger');
const authService = new AuthService(UserModel, Logger);
await expect(authService.SignIn('[email protected]', 'bliepbloep')).rejects.toThrow();
});
})
});
Note: This is when running your own mongoDB instance Changes in current implementation:
- loaders\index.ts returns mongoConnection
- loaders\mongoose.ts returns connection instead of connection.connection.db
it would indeed be great to see at least 1 beautiful unit test...
@leanderhoedt few things that could be improved in your sample:
- you should use something like module-alias to avoid relatives path like
../../../src/loaders
- to avoid code duplication, it would be also preferable to have environment set up using jest.setupFiles so that you don't have to define
beforeAll
in each file
@leanderhoedt the auth service in my code needs some more properties like mailer and dispatcher... I've tried with Container.get(AuthService)... but then the dependencies wont be injected...
Im unable to add this test :(
@domsen123 Any luck on the tests?
@syffs how would one use relative paths with the current bulletproof setup? As tests is outside the root dir
@Nikola-Milovic nope... but didn't check "Dependency Injection in tests #70"