Skip to content

Commit b66ccd5

Browse files
committed
Corrected tests
1 parent c136437 commit b66ccd5

File tree

4 files changed

+115
-111
lines changed

4 files changed

+115
-111
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,88 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22
import { VehicleBrandsController } from './vehicle-brands.controller';
33
import { VehicleBrandsService } from './vehicle-brands.service';
4+
import { PageDto } from '../common/pages/dto/page.dto';
5+
import { PageOptionsDto } from '../common/pages/dto/page-options.dto';
46
import { CreateVehicleBrandDto } from './dto/create-vehicle-brand.dto';
57
import { UpdateVehicleBrandDto } from './dto/update-vehicle-brand.dto';
6-
7-
const mockVehicleBrandsService = {
8-
create: jest.fn(),
9-
findAll: jest.fn(),
10-
findOne: jest.fn(),
11-
update: jest.fn(),
12-
remove: jest.fn(),
13-
};
8+
import { VehicleBrandDto } from './dto/vehicle-brand.dto';
149

1510
describe('VehicleBrandsController', () => {
1611
let controller: VehicleBrandsController;
12+
let service: VehicleBrandsService;
1713

1814
beforeEach(async () => {
1915
const module: TestingModule = await Test.createTestingModule({
2016
controllers: [VehicleBrandsController],
2117
providers: [
2218
{
2319
provide: VehicleBrandsService,
24-
useValue: mockVehicleBrandsService,
20+
useValue: {
21+
create: jest.fn(),
22+
findVehicleBrands: jest.fn(),
23+
findOne: jest.fn(),
24+
update: jest.fn(),
25+
},
2526
},
2627
],
2728
}).compile();
2829

2930
controller = module.get<VehicleBrandsController>(VehicleBrandsController);
31+
service = module.get<VehicleBrandsService>(VehicleBrandsService);
3032
});
3133

3234
it('should be defined', () => {
3335
expect(controller).toBeDefined();
3436
});
3537

3638
describe('create', () => {
37-
it('should create a new vehicle brand', async () => {
39+
it('should call service.create with correct parameters', async () => {
3840
const createVehicleBrandDto: CreateVehicleBrandDto = { name: 'Toyota' };
39-
mockVehicleBrandsService.create.mockResolvedValue(createVehicleBrandDto);
41+
const result = new VehicleBrandDto();
42+
jest.spyOn(service, 'create').mockResolvedValue(result);
4043

41-
expect(await controller.create(createVehicleBrandDto)).toEqual(
42-
createVehicleBrandDto
43-
);
44-
expect(mockVehicleBrandsService.create).toHaveBeenCalledWith(
45-
createVehicleBrandDto
46-
);
44+
expect(await controller.create(createVehicleBrandDto)).toBe(result);
45+
expect(service.create).toHaveBeenCalledWith(createVehicleBrandDto);
4746
});
4847
});
4948

50-
describe('findAll', () => {
51-
it('should return an array of vehicle brands', async () => {
52-
const result = [{ id: 1, name: 'Toyota' }];
53-
mockVehicleBrandsService.findAll.mockResolvedValue(result);
49+
describe('findVehicleBrands', () => {
50+
it('should call service.findVehicleBrands with correct parameters', async () => {
51+
const pageOptionsDto: PageOptionsDto = {
52+
page: 1,
53+
take: 10,
54+
skip: 0,
55+
};
56+
const result = { data: [], meta: {} };
57+
jest
58+
.spyOn(service, 'findVehicleBrands')
59+
.mockResolvedValue(result as PageDto<VehicleBrandDto>);
5460

55-
expect(await controller.findAll()).toEqual(result);
61+
expect(await controller.findVehicleBrands(pageOptionsDto)).toBe(result);
62+
expect(service.findVehicleBrands).toHaveBeenCalledWith(pageOptionsDto);
5663
});
5764
});
5865

5966
describe('findOne', () => {
60-
it('should return a vehicle brand by id', async () => {
61-
const result = { id: 1, name: 'Toyota' };
62-
mockVehicleBrandsService.findOne.mockResolvedValue(result);
67+
it('should call service.findOne with correct parameters', async () => {
68+
const id = 1;
69+
const result = new VehicleBrandDto();
70+
jest.spyOn(service, 'findOne').mockResolvedValue(result);
6371

64-
expect(await controller.findOne('1')).toEqual(result);
65-
expect(mockVehicleBrandsService.findOne).toHaveBeenCalledWith(1);
72+
expect(await controller.findOne(id)).toBe(result);
73+
expect(service.findOne).toHaveBeenCalledWith(id);
6674
});
6775
});
6876

6977
describe('update', () => {
70-
it('should update a vehicle brand', async () => {
71-
const updateVehicleBrandDto: UpdateVehicleBrandDto = { name: 'Toyota' };
72-
const result = { id: 1, name: 'Toyota' };
73-
mockVehicleBrandsService.update.mockResolvedValue(result);
74-
75-
expect(await controller.update('1', updateVehicleBrandDto)).toEqual(
76-
result
77-
);
78-
expect(mockVehicleBrandsService.update).toHaveBeenCalledWith(
79-
1,
80-
updateVehicleBrandDto
81-
);
82-
});
83-
});
84-
85-
describe('remove', () => {
86-
it('should remove a vehicle brand', async () => {
87-
const result = { id: 1, name: 'Toyota' };
88-
mockVehicleBrandsService.remove.mockResolvedValue(result);
78+
it('should call service.update with correct parameters', async () => {
79+
const id = 1;
80+
const updateVehicleBrandDto: UpdateVehicleBrandDto = { name: 'Honda' };
81+
const result = new VehicleBrandDto();
82+
jest.spyOn(service, 'update').mockResolvedValue(result);
8983

90-
expect(await controller.remove('1')).toEqual(result);
91-
expect(mockVehicleBrandsService.remove).toHaveBeenCalledWith(1);
84+
expect(await controller.update(id, updateVehicleBrandDto)).toBe(result);
85+
expect(service.update).toHaveBeenCalledWith(id, updateVehicleBrandDto);
9286
});
9387
});
9488
});

apps/car-rental-backend/src/vehicle-brands/vehicle-brands.controller.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class VehicleBrandsController {
2525
@Post()
2626
@HttpCode(HttpStatus.CREATED)
2727
@ApiOkResponse({ type: VehicleBrandDto })
28-
@ApiConflictResponse({ description: 'Vehicle brand already exists' })
28+
@ApiConflictResponse({ description: 'Vehicle brand already exists', example: { status: 409, error: 'Vehicle brand already exists' } })
2929
create(@Body() createVehicleBrandDto: CreateVehicleBrandDto) {
3030
return this.vehicleBrandsService.create(createVehicleBrandDto);
3131
}
@@ -40,15 +40,16 @@ export class VehicleBrandsController {
4040
@Get(':id')
4141
@HttpCode(HttpStatus.OK)
4242
@ApiOkResponse({ type: VehicleBrandDto })
43-
@ApiNotFoundResponse({ description: 'Vehicle brand not found' })
43+
@ApiNotFoundResponse({ description: 'Vehicle brand not found', example: { status: 404, error: 'Vehicle brand not found' } })
4444
findOne(@Param('id') id: number) {
4545
return this.vehicleBrandsService.findOne(id);
4646
}
4747

4848
@Patch(':id')
4949
@HttpCode(HttpStatus.OK)
5050
@ApiOkResponse({ type: VehicleBrandDto })
51-
@ApiNotFoundResponse({ description: 'Vehicle brand not found' })
51+
@ApiNotFoundResponse({ description: 'Vehicle brand not found', example: { status: 404, error: 'Vehicle brand not found' } })
52+
@ApiConflictResponse({ description: 'Vehicle brand already exists', example: { status: 409, error: 'Vehicle brand already exists' } })
5253
update(
5354
@Param('id') id: number,
5455
@Body() updateVehicleBrandDto: UpdateVehicleBrandDto
@@ -59,7 +60,7 @@ export class VehicleBrandsController {
5960
@Delete(':id')
6061
@HttpCode(HttpStatus.NO_CONTENT)
6162
@ApiNoContentResponse({ description: 'Vehicle brand removed' })
62-
@ApiNotFoundResponse({ description: 'Vehicle brand not found' })
63+
@ApiNotFoundResponse({ description: 'Vehicle brand not found', example: { status: 404, error: 'Vehicle brand not found' } })
6364
remove(@Param('id') id: number) {
6465
return this.vehicleBrandsService.remove(id);
6566
}

apps/car-rental-backend/src/vehicle-brands/vehicle-brands.service.spec.ts

+48-50
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@ import { Test, TestingModule } from '@nestjs/testing';
22
import { VehicleBrandsService } from './vehicle-brands.service';
33
import { getRepositoryToken } from '@nestjs/typeorm';
44
import { Repository } from 'typeorm';
5-
import { VehicleBrand } from './entities/vehicle-brand.entity';
65
import { HttpException, HttpStatus } from '@nestjs/common';
7-
8-
const mockVehicleBrandRepository = {
9-
find: jest.fn(),
10-
findOneBy: jest.fn(),
11-
save: jest.fn(),
12-
};
6+
import { UpdateVehicleBrandDto } from './dto/update-vehicle-brand.dto';
7+
import { VehicleBrand } from './entities/vehicle-brand.entity';
138

149
describe('VehicleBrandsService', () => {
1510
let service: VehicleBrandsService;
@@ -21,74 +16,77 @@ describe('VehicleBrandsService', () => {
2116
VehicleBrandsService,
2217
{
2318
provide: getRepositoryToken(VehicleBrand),
24-
useValue: mockVehicleBrandRepository,
19+
useClass: Repository,
2520
},
2621
],
2722
}).compile();
2823

2924
service = module.get<VehicleBrandsService>(VehicleBrandsService);
30-
repository = module.get<Repository<VehicleBrand>>(
31-
getRepositoryToken(VehicleBrand)
32-
);
25+
repository = module.get<Repository<VehicleBrand>>(getRepositoryToken(VehicleBrand));
3326
});
3427

35-
it('should be defined', () => {
36-
expect(service).toBeDefined();
37-
});
38-
39-
describe('create', () => {
40-
it('should throw an error if vehicle brand already exists', async () => {
41-
const createVehicleBrandDto = { name: 'Toyota' };
42-
jest
43-
.spyOn(service, 'findByName')
44-
.mockResolvedValue({ id: 1, name: 'Toyota' } as VehicleBrand);
28+
describe('update', () => {
29+
it('should throw conflict exception if vehicle brand name already exists', async () => {
30+
const updateVehicleBrandDto: UpdateVehicleBrandDto = { name: 'Toyota' };
31+
jest.spyOn(service, 'findByName').mockResolvedValue(new VehicleBrand());
4532

46-
await expect(service.create(createVehicleBrandDto)).rejects.toThrow(
33+
await expect(service.update(1, updateVehicleBrandDto)).rejects.toThrow(
4734
new HttpException(
48-
{
49-
status: HttpStatus.CONFLICT,
50-
error: 'Vehicle brand already exists',
51-
},
35+
{ status: HttpStatus.CONFLICT, error: 'Vehicle brand already exists' },
5236
HttpStatus.CONFLICT
5337
)
5438
);
5539
});
5640

57-
it('should save a new vehicle brand', async () => {
58-
const createVehicleBrandDto = { name: 'Toyota' };
59-
jest.spyOn(service, 'findByName').mockResolvedValue(null);
60-
mockVehicleBrandRepository.save.mockResolvedValue(createVehicleBrandDto);
41+
it('should throw not found exception if vehicle brand is not found by ID', async () => {
42+
const updateVehicleBrandDto: UpdateVehicleBrandDto = { name: 'Toyota' };
43+
jest.spyOn(service, 'findByName').mockRejectedValue({ status: HttpStatus.NOT_FOUND });
44+
jest.spyOn(repository, 'findOneBy').mockResolvedValue(null);
6145

62-
expect(await service.create(createVehicleBrandDto)).toEqual(
63-
createVehicleBrandDto
64-
);
65-
expect(mockVehicleBrandRepository.save).toHaveBeenCalledWith(
66-
createVehicleBrandDto
46+
await expect(service.update(1, updateVehicleBrandDto)).rejects.toThrow(
47+
new HttpException(
48+
{ status: HttpStatus.NOT_FOUND, error: 'Vehicle brand not found' },
49+
HttpStatus.NOT_FOUND
50+
)
6751
);
6852
});
69-
});
7053

71-
describe('findAll', () => {
72-
it('should return an array of vehicle brands', async () => {
73-
const result = [{ id: 1, name: 'Toyota' }];
74-
mockVehicleBrandRepository.find.mockResolvedValue(result);
54+
it('should update and return the vehicle brand', async () => {
55+
const updateVehicleBrandDto: UpdateVehicleBrandDto = { name: 'Toyota' };
56+
const vehicleBrand = new VehicleBrand();
57+
jest.spyOn(service, 'findByName').mockRejectedValue({ status: HttpStatus.NOT_FOUND });
58+
jest.spyOn(repository, 'findOneBy').mockResolvedValue(vehicleBrand);
59+
jest.spyOn(repository, 'save').mockResolvedValue(vehicleBrand);
7560

76-
expect(await service.findAll()).toEqual(result);
61+
const result = await service.update(1, updateVehicleBrandDto);
62+
expect(result).toBe(vehicleBrand);
63+
expect(repository.save).toHaveBeenCalledWith({ id: 1, name: 'Toyota' });
64+
expect(repository.findOneBy).toHaveBeenCalledWith({ id: 1 });
7765
});
7866
});
7967

80-
describe('findOne', () => {
81-
it('should return a vehicle brand by id', async () => {
82-
const result = { id: 1, name: 'Toyota' };
83-
mockVehicleBrandRepository.findOneBy.mockResolvedValue(result);
68+
describe('remove', () => {
69+
it('should throw not found exception if vehicle brand is not found by ID', async () => {
70+
jest.spyOn(repository, 'findOneBy').mockResolvedValue(null);
8471

85-
expect(await service.findOne(1)).toEqual(result);
72+
await expect(service.remove(1)).rejects.toThrow(
73+
new HttpException(
74+
{ status: HttpStatus.NOT_FOUND, error: 'Vehicle brand not found' },
75+
HttpStatus.NOT_FOUND
76+
)
77+
);
8678
});
8779

88-
it('should return null if vehicle brand not found', async () => {
89-
mockVehicleBrandRepository.findOneBy.mockResolvedValue(null);
80+
it('should remove the vehicle brand', async () => {
81+
const vehicleBrand = new VehicleBrand();
82+
const deleteResult = { affected: 1, raw: [] };
83+
jest.spyOn(repository, 'findOneBy').mockResolvedValue(vehicleBrand);
84+
jest.spyOn(repository, 'delete').mockResolvedValue(deleteResult);
9085

91-
expect(await service.findOne(1)).toBeNull();
86+
const result = await service.remove(1);
87+
expect(result).toBe(deleteResult);
88+
expect(repository.findOneBy).toHaveBeenCalledWith({ id: 1 });
89+
expect(repository.delete).toHaveBeenCalledWith(1);
9290
});
9391
});
94-
});
92+
});

apps/car-rental-backend/src/vehicle-brands/vehicle-brands.service.ts

+20-9
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,7 @@ export class VehicleBrandsService {
3939
}
4040

4141
async findOne(id: number) {
42-
const vehicle = await this.vehicleBrandsRepository.findOneBy({ id });
43-
if (!vehicle) {
44-
throw new HttpException(
45-
{ status: HttpStatus.NOT_FOUND, error: 'Vehicle brand not found' },
46-
HttpStatus.NOT_FOUND
47-
);
48-
}
49-
return vehicle;
42+
return this.vehicleBrandsRepository.findOneBy({ id });
5043
}
5144

5245
async findByName(name: string) {
@@ -61,14 +54,32 @@ export class VehicleBrandsService {
6154
}
6255

6356
async update(id: number, updateVehicleBrandDto: UpdateVehicleBrandDto) {
57+
const { name } = updateVehicleBrandDto;
58+
let vehicleBrand: VehicleBrand;
59+
try {
60+
vehicleBrand = await this.findByName(name);
61+
} catch (error) {
62+
if (error.status !== HttpStatus.NOT_FOUND) {
63+
throw error;
64+
}
65+
}
66+
if (vehicleBrand) {
67+
throw new HttpException(
68+
{ status: HttpStatus.CONFLICT, error: 'Vehicle brand already exists' },
69+
HttpStatus.CONFLICT
70+
);
71+
}
6472
const vehicle = await this.vehicleBrandsRepository.findOneBy({ id });
6573
if (!vehicle) {
6674
throw new HttpException(
6775
{ status: HttpStatus.NOT_FOUND, error: 'Vehicle brand not found' },
6876
HttpStatus.NOT_FOUND
6977
);
7078
}
71-
return this.vehicleBrandsRepository.update(id, updateVehicleBrandDto);
79+
await this.vehicleBrandsRepository.save({ id, name });
80+
return await this.vehicleBrandsRepository.findOneBy({
81+
id,
82+
});
7283
}
7384

7485
async remove(id: number) {

0 commit comments

Comments
 (0)