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

View File

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

View File

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

View File

@ -19,9 +19,16 @@ const newUserRequest: CreateUserRequest = {
const newUserCommand: CreateUserCommand = new CreateUserCommand(newUserRequest); const newUserCommand: CreateUserCommand = new CreateUserCommand(newUserRequest);
const mockUsersRepository = { const mockUsersRepository = {
create: jest.fn().mockResolvedValue({ create: jest
.fn()
.mockImplementationOnce(() => {
return Promise.resolve({
...newUserRequest, ...newUserRequest,
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
});
})
.mockImplementation(() => {
throw new Error('Already exists');
}), }),
}; };
@ -67,5 +74,11 @@ describe('CreateUserUseCase', () => {
expect(newUser.lastName).toBe(newUserRequest.lastName); expect(newUser.lastName).toBe(newUserRequest.lastName);
expect(newUser.uuid).toBeDefined(); 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,7 +30,9 @@ const mockUsers = [
]; ];
const mockUsersRepository = { const mockUsersRepository = {
delete: jest.fn().mockImplementation((uuid: string) => { delete: jest
.fn()
.mockImplementationOnce((uuid: string) => {
let savedUser = {}; let savedUser = {};
mockUsers.forEach((user, index) => { mockUsers.forEach((user, index) => {
if (user.uuid === uuid) { if (user.uuid === uuid) {
@ -39,6 +41,9 @@ const mockUsersRepository = {
} }
}); });
return savedUser; return savedUser;
})
.mockImplementation(() => {
throw new Error('Error');
}), }),
}; };
@ -84,5 +89,10 @@ describe('DeleteUserUseCase', () => {
const deletedUser = mockUsers.find((user) => user.uuid === savedUuid); const deletedUser = mockUsers.find((user) => user.uuid === savedUuid);
expect(deletedUser).toBeUndefined(); 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 { Test, TestingModule } from '@nestjs/testing';
import { UsersRepository } from '../../adapters/secondaries/users.repository'; 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 { FindAllUsersUseCase } from '../../domain/usecases/find-all-users.usecase';
import { FindAllUsersQuery } from '../../queries/find-all-users.query'; 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 = [ const mockUsers = [
{ {
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
@ -57,7 +66,7 @@ describe('FindAllUsersUseCase', () => {
describe('execute', () => { describe('execute', () => {
it('should return an array filled with users', async () => { 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); expect(users).toBe(mockUsers);
}); });

View File

@ -1,6 +1,8 @@
import { NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; import { LoggingMessager } from '../../adapters/secondaries/logging.messager';
import { UsersRepository } from '../../adapters/secondaries/users.repository'; 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 { FindUserByUuidUseCase } from '../../domain/usecases/find-user-by-uuid.usecase';
import { FindUserByUuidQuery } from '../../queries/find-user-by-uuid.query'; import { FindUserByUuidQuery } from '../../queries/find-user-by-uuid.query';
@ -13,9 +15,14 @@ const mockUser = {
}; };
const mockUserRepository = { const mockUserRepository = {
findOneByUuid: jest
.fn()
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
findOneByUuid: jest.fn().mockImplementation((query?: FindUserByUuidQuery) => { .mockImplementationOnce((query?: FindUserByUuidQuery) => {
return Promise.resolve(mockUser); return Promise.resolve(mockUser);
})
.mockImplementation(() => {
return Promise.resolve(undefined);
}), }),
}; };
@ -53,11 +60,23 @@ describe('FindUserByUuidUseCase', () => {
describe('execute', () => { describe('execute', () => {
it('should return a user', async () => { it('should return a user', async () => {
const findUserByUuidRequest: FindUserByUuidRequest =
new FindUserByUuidRequest();
findUserByUuidRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91';
const user = await findUserByUuidUseCase.execute( const user = await findUserByUuidUseCase.execute(
new FindUserByUuidQuery('bb281075-1b98-4456-89d6-c643d3044a91'), new FindUserByUuidQuery(findUserByUuidRequest),
); );
expect(user).toBe(mockUser); 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,10 +24,15 @@ const updateUserCommand: UpdateUserCommand = new UpdateUserCommand(
); );
const mockUsersRepository = { const mockUsersRepository = {
update: jest.fn().mockImplementation((uuid: string, params: any) => { update: jest
.fn()
.mockImplementationOnce((uuid: string, params: any) => {
originalUser.lastName = params.lastName; originalUser.lastName = params.lastName;
return Promise.resolve(originalUser); return Promise.resolve(originalUser);
})
.mockImplementation(() => {
throw new Error('Error');
}), }),
}; };
@ -75,5 +80,10 @@ describe('UpdateUserUseCase', () => {
expect(updatedUser.lastName).toBe(updateUserRequest.lastName); 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);
});
}); });
}); });