better testing

This commit is contained in:
Gsk54 2023-01-11 11:26:58 +01:00
parent cc7aace334
commit 9eab64bb00
8 changed files with 94 additions and 32 deletions

View File

@ -19,7 +19,7 @@
"test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage",
"test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose",
"test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/'",
"test:cov": "npm run migrate:test && dotenv -e .env.test -- jest --coverage",
"test:cov": "jest --testPathPattern 'tests/unit/' --coverage",
"test:e2e": "jest --config ./test/jest-e2e.json",
"migrate": "docker exec v3-user sh -c 'npx prisma migrate dev'",
"migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy",
@ -70,6 +70,7 @@
"json",
"ts"
],
"modulePathIgnorePatterns": [".controller.ts",".module.ts"],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {

View File

@ -3,7 +3,7 @@ import { InjectMapper } from '@automapper/nestjs';
import { Controller, UsePipes } from '@nestjs/common';
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import { GrpcMethod, RpcException } from '@nestjs/microservices';
import { DatabaseException } from 'src/modules/database/src/exceptions/DatabaseException';
import { DatabaseException } from '../../../database/src/exceptions/DatabaseException';
import { CreateUserCommand } from '../../commands/create-user.command';
import { DeleteUserCommand } from '../../commands/delete-user.command';
import { UpdateUserCommand } from '../../commands/update-user.command';
@ -48,9 +48,7 @@ export class UsersController {
@GrpcMethod('UsersService', 'FindOneByUuid')
async findOneByUuid(data: FindUserByUuidRequest): Promise<UserPresenter> {
try {
const user = await this._queryBus.execute(
new FindUserByUuidQuery(data.uuid),
);
const user = await this._queryBus.execute(new FindUserByUuidQuery(data));
return this._mapper.map(user, User, UserPresenter);
} catch (error) {
throw new RpcException({

View File

@ -1,7 +1,9 @@
import { FindUserByUuidRequest } from '../domain/dtos/find-user-by-uuid.request';
export class FindUserByUuidQuery {
readonly uuid: string;
constructor(uuid: string) {
this.uuid = uuid;
constructor(findUserByUuidRequest: FindUserByUuidRequest) {
this.uuid = findUserByUuidRequest.uuid;
}
}

View File

@ -19,10 +19,17 @@ const newUserRequest: CreateUserRequest = {
const newUserCommand: CreateUserCommand = new CreateUserCommand(newUserRequest);
const mockUsersRepository = {
create: jest.fn().mockResolvedValue({
...newUserRequest,
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
}),
create: jest
.fn()
.mockImplementationOnce(() => {
return Promise.resolve({
...newUserRequest,
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
});
})
.mockImplementation(() => {
throw new Error('Already exists');
}),
};
const mockMessager = {
@ -67,5 +74,11 @@ describe('CreateUserUseCase', () => {
expect(newUser.lastName).toBe(newUserRequest.lastName);
expect(newUser.uuid).toBeDefined();
});
it('should throw an error if user already exists', async () => {
await expect(
createUserUseCase.execute(newUserCommand),
).rejects.toBeInstanceOf(Error);
});
});
});

View File

@ -30,16 +30,21 @@ const mockUsers = [
];
const mockUsersRepository = {
delete: jest.fn().mockImplementation((uuid: string) => {
let savedUser = {};
mockUsers.forEach((user, index) => {
if (user.uuid === uuid) {
savedUser = { ...user };
mockUsers.splice(index, 1);
}
});
return savedUser;
}),
delete: jest
.fn()
.mockImplementationOnce((uuid: string) => {
let savedUser = {};
mockUsers.forEach((user, index) => {
if (user.uuid === uuid) {
savedUser = { ...user };
mockUsers.splice(index, 1);
}
});
return savedUser;
})
.mockImplementation(() => {
throw new Error('Error');
}),
};
const mockMessager = {
@ -84,5 +89,10 @@ describe('DeleteUserUseCase', () => {
const deletedUser = mockUsers.find((user) => user.uuid === savedUuid);
expect(deletedUser).toBeUndefined();
});
it('should throw an error if user does not exist', async () => {
await expect(
deleteUserUseCase.execute(new DeleteUserCommand('wrong uuid')),
).rejects.toBeInstanceOf(Error);
});
});
});

View File

@ -1,8 +1,17 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UsersRepository } from '../../adapters/secondaries/users.repository';
import { FindAllUsersRequest } from '../../domain/dtos/find-all-users.request';
import { FindAllUsersUseCase } from '../../domain/usecases/find-all-users.usecase';
import { FindAllUsersQuery } from '../../queries/find-all-users.query';
const findAllUsersRequest: FindAllUsersRequest = new FindAllUsersRequest();
findAllUsersRequest.page = 1;
findAllUsersRequest.perPage = 10;
const findAllUsersQuery: FindAllUsersQuery = new FindAllUsersQuery(
findAllUsersRequest,
);
const mockUsers = [
{
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
@ -57,7 +66,7 @@ describe('FindAllUsersUseCase', () => {
describe('execute', () => {
it('should return an array filled with users', async () => {
const users = await findAllUsersUseCase.execute(new FindAllUsersQuery());
const users = await findAllUsersUseCase.execute(findAllUsersQuery);
expect(users).toBe(mockUsers);
});

View File

@ -1,6 +1,8 @@
import { NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { UsersRepository } from '../../adapters/secondaries/users.repository';
import { FindUserByUuidRequest } from '../../domain/dtos/find-user-by-uuid.request';
import { FindUserByUuidUseCase } from '../../domain/usecases/find-user-by-uuid.usecase';
import { FindUserByUuidQuery } from '../../queries/find-user-by-uuid.query';
@ -13,10 +15,15 @@ const mockUser = {
};
const mockUserRepository = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
findOneByUuid: jest.fn().mockImplementation((query?: FindUserByUuidQuery) => {
return Promise.resolve(mockUser);
}),
findOneByUuid: jest
.fn()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.mockImplementationOnce((query?: FindUserByUuidQuery) => {
return Promise.resolve(mockUser);
})
.mockImplementation(() => {
return Promise.resolve(undefined);
}),
};
const mockMessager = {
@ -53,11 +60,23 @@ describe('FindUserByUuidUseCase', () => {
describe('execute', () => {
it('should return a user', async () => {
const findUserByUuidRequest: FindUserByUuidRequest =
new FindUserByUuidRequest();
findUserByUuidRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91';
const user = await findUserByUuidUseCase.execute(
new FindUserByUuidQuery('bb281075-1b98-4456-89d6-c643d3044a91'),
new FindUserByUuidQuery(findUserByUuidRequest),
);
expect(user).toBe(mockUser);
});
it('should throw an error if user does not exist', async () => {
const findUserByUuidRequest: FindUserByUuidRequest =
new FindUserByUuidRequest();
findUserByUuidRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a90';
await expect(
findUserByUuidUseCase.execute(
new FindUserByUuidQuery(findUserByUuidRequest),
),
).rejects.toBeInstanceOf(NotFoundException);
});
});
});

View File

@ -24,11 +24,16 @@ const updateUserCommand: UpdateUserCommand = new UpdateUserCommand(
);
const mockUsersRepository = {
update: jest.fn().mockImplementation((uuid: string, params: any) => {
originalUser.lastName = params.lastName;
update: jest
.fn()
.mockImplementationOnce((uuid: string, params: any) => {
originalUser.lastName = params.lastName;
return Promise.resolve(originalUser);
}),
return Promise.resolve(originalUser);
})
.mockImplementation(() => {
throw new Error('Error');
}),
};
const mockMessager = {
@ -75,5 +80,10 @@ describe('UpdateUserUseCase', () => {
expect(updatedUser.lastName).toBe(updateUserRequest.lastName);
});
it('should throw an error if user does not exist', async () => {
await expect(
updateUserUseCase.execute(updateUserCommand),
).rejects.toBeInstanceOf(Error);
});
});
});