Skip to content

Commit b38817b

Browse files
authored
Merge pull request #193 from boostcampwm-2024/feature-be-#129
엣지 API 테스트코드 작성
2 parents 93fe456 + 268743e commit b38817b

File tree

6 files changed

+269
-16
lines changed

6 files changed

+269
-16
lines changed

.gitignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,4 @@ lerna-debug.log*
4444

4545
# IDE - VSCode
4646
.vscode/*
47-
!.vscode/settings.json
48-
!.vscode/tasks.json
49-
!.vscode/launch.json
50-
!.vscode/extensions.json
5147
apps/backend/db.sqlite

.vscode/settings.json

Whitespace-only changes.
Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,120 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22
import { EdgeController } from './edge.controller';
33
import { EdgeService } from './edge.service';
4+
import { CreateEdgeDto } from './dtos/createEdge.dto';
5+
import { EdgeResponseMessage } from './edge.controller';
6+
import { EdgeNotFoundException } from '../exception/edge.exception';
7+
import { Edge } from './edge.entity';
8+
import { Node } from '../node/node.entity';
49

510
describe('EdgeController', () => {
611
let controller: EdgeController;
12+
let edgeService: EdgeService;
713

814
beforeEach(async () => {
915
const module: TestingModule = await Test.createTestingModule({
1016
controllers: [EdgeController],
1117
providers: [
1218
{
1319
provide: EdgeService,
14-
useValue: {},
20+
useValue: {
21+
createEdge: jest.fn(),
22+
deleteEdge: jest.fn(),
23+
findEdges: jest.fn(),
24+
},
1525
},
1626
],
1727
}).compile();
1828

1929
controller = module.get<EdgeController>(EdgeController);
30+
edgeService = module.get<EdgeService>(EdgeService);
2031
});
2132

2233
it('컨트롤러 클래스가 정상적으로 인스턴스화된다.', () => {
2334
expect(controller).toBeDefined();
2435
});
36+
37+
describe('createEdge', () => {
38+
it('엣지가 성공적으로 만들어진다', async () => {
39+
const dto: CreateEdgeDto = { fromNode: 1, toNode: 3 };
40+
const expectedResponse = {
41+
message: EdgeResponseMessage.EDGE_CREATED,
42+
};
43+
44+
jest.spyOn(edgeService, 'createEdge').mockResolvedValue(undefined);
45+
const result = await controller.createEdge(dto);
46+
47+
expect(edgeService.createEdge).toHaveBeenCalledWith(dto);
48+
expect(result).toEqual(expectedResponse);
49+
});
50+
});
51+
52+
describe('deleteEdge', () => {
53+
it('id에 해당하는 엣지를 찾아 삭제한다.', async () => {
54+
const id = 2;
55+
const expectedResponse = {
56+
message: EdgeResponseMessage.EDGE_DELETED,
57+
};
58+
59+
const result = await controller.deleteEdge(id);
60+
61+
expect(edgeService.deleteEdge).toHaveBeenCalledWith(id);
62+
expect(result).toEqual(expectedResponse);
63+
});
64+
65+
it('id에 해당하는 엣지가 존재하지 않으면 NodeNotFoundException을 throw한다.', async () => {
66+
jest
67+
.spyOn(edgeService, 'deleteEdge')
68+
.mockRejectedValue(new EdgeNotFoundException());
69+
70+
await expect(controller.deleteEdge(1)).rejects.toThrow(
71+
EdgeNotFoundException,
72+
);
73+
});
74+
});
75+
76+
describe('findEdges', () => {
77+
it('모든 엣지 목록을 반환한다.', async () => {
78+
const node3 = {
79+
id: 3,
80+
x: 0,
81+
y: 0,
82+
title: 'Node Title',
83+
page: null,
84+
outgoingEdges: [],
85+
incomingEdges: [],
86+
} as Node;
87+
const node4 = {
88+
id: 4,
89+
x: 0,
90+
y: 0,
91+
title: 'Node Title',
92+
page: null,
93+
outgoingEdges: [],
94+
incomingEdges: [],
95+
} as Node;
96+
const node5 = {
97+
id: 5,
98+
x: 0,
99+
y: 0,
100+
title: 'Node Title',
101+
page: null,
102+
outgoingEdges: [],
103+
incomingEdges: [],
104+
} as Node;
105+
106+
const expectedEdges = [
107+
{ id: 1, fromNode: node3, toNode: node5 },
108+
{ id: 2, fromNode: node3, toNode: node4 },
109+
] as Edge[];
110+
node3.outgoingEdges = [];
111+
112+
jest.spyOn(edgeService, 'findEdges').mockResolvedValue(expectedEdges);
113+
114+
await expect(controller.findEdges()).resolves.toEqual({
115+
message: EdgeResponseMessage.EDGE_ALL_RETURNED,
116+
edges: expectedEdges,
117+
});
118+
});
119+
});
25120
});

apps/backend/src/edge/edge.controller.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ export class EdgeController {
3333
})
3434
@Get('/')
3535
@HttpCode(HttpStatus.OK)
36-
async getNodes() {
37-
const nodes = await this.edgeService.findEdges();
36+
async findEdges() {
37+
const edges = await this.edgeService.findEdges();
3838
return {
3939
message: EdgeResponseMessage.EDGE_ALL_RETURNED,
40-
nodes: nodes,
40+
edges: edges,
4141
};
4242
}
4343

@@ -56,7 +56,7 @@ export class EdgeController {
5656
@ApiOperation({ summary: '엣지를 삭제합니다.' })
5757
@Delete('/:id')
5858
@HttpCode(HttpStatus.OK)
59-
async deleteNode(
59+
async deleteEdge(
6060
@Param('id', ParseIntPipe) id: number,
6161
): Promise<{ message: string }> {
6262
await this.edgeService.deleteEdge(id);

apps/backend/src/edge/edge.entity.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import {
33
Entity,
44
PrimaryGeneratedColumn,
5-
Column,
5+
// Column,
66
ManyToOne,
77
JoinColumn,
88
} from 'typeorm';
@@ -21,9 +21,9 @@ export class Edge {
2121
@JoinColumn({ name: 'to_node_id' })
2222
toNode: Node;
2323

24-
@Column({ nullable: true })
25-
type: string;
24+
// @Column({ nullable: true })
25+
// type: string;
2626

27-
@Column({ nullable: true })
28-
color: string;
27+
// @Column({ nullable: true })
28+
// color: string;
2929
}

apps/backend/src/edge/edge.service.spec.ts

Lines changed: 164 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,191 @@ import { Test, TestingModule } from '@nestjs/testing';
22
import { EdgeService } from './edge.service';
33
import { EdgeRepository } from './edge.repository';
44
import { NodeRepository } from '../node/node.repository';
5+
import { CreateEdgeDto } from './dtos/createEdge.dto';
6+
import { Edge } from './edge.entity';
7+
import { Node } from '../node/node.entity';
8+
import { EdgeNotFoundException } from '../exception/edge.exception';
59

610
describe('EdgeService', () => {
711
let service: EdgeService;
12+
let edgeRepository: jest.Mocked<EdgeRepository>;
13+
let nodeRepository: jest.Mocked<NodeRepository>;
814

915
beforeEach(async () => {
1016
const module: TestingModule = await Test.createTestingModule({
1117
providers: [
1218
EdgeService,
1319
{
1420
provide: EdgeRepository,
15-
useValue: {},
21+
useValue: {
22+
create: jest.fn(),
23+
save: jest.fn(),
24+
delete: jest.fn(),
25+
findOneBy: jest.fn(),
26+
find: jest.fn(),
27+
},
1628
},
1729
{
1830
provide: NodeRepository,
19-
useValue: {},
31+
useValue: {
32+
save: jest.fn(),
33+
findOneBy: jest.fn(),
34+
},
2035
},
2136
],
2237
}).compile();
2338

2439
service = module.get<EdgeService>(EdgeService);
40+
edgeRepository = module.get(EdgeRepository);
41+
nodeRepository = module.get(NodeRepository);
2542
});
2643

2744
it('서비스 클래스가 정상적으로 인스턴스화된다.', () => {
2845
expect(service).toBeDefined();
2946
});
47+
48+
describe('createEdge', () => {
49+
it('새로운 엣지를 만들어 노드와 노드를 연결하는 연결한다.', async () => {
50+
const dto: CreateEdgeDto = { fromNode: 3, toNode: 5 };
51+
const fromNode = {
52+
id: 3,
53+
x: 0,
54+
y: 0,
55+
title: 'Node Title',
56+
page: null,
57+
outgoingEdges: [],
58+
incomingEdges: [],
59+
} as Node;
60+
const toNode = {
61+
id: 5,
62+
x: 0,
63+
y: 0,
64+
title: 'Node Title',
65+
page: null,
66+
outgoingEdges: [],
67+
incomingEdges: [],
68+
} as Node;
69+
const edge = {
70+
id: 1,
71+
fromNode: fromNode,
72+
toNode: toNode,
73+
} as Edge;
74+
75+
jest
76+
.spyOn(nodeRepository, 'findOneBy')
77+
.mockResolvedValueOnce(fromNode) // 첫 번째 호출: fromNode
78+
.mockResolvedValueOnce(toNode); // 두 번째 호출: toNode
79+
jest.spyOn(edgeRepository, 'save').mockResolvedValue(edge);
80+
81+
const result = await service.createEdge(dto);
82+
83+
expect(result).toEqual(edge);
84+
expect(edgeRepository.save).toHaveBeenCalledTimes(1);
85+
expect(nodeRepository.findOneBy).toHaveBeenCalledTimes(2);
86+
});
87+
});
88+
89+
describe('deleteEdge', () => {
90+
it('엣지를 성공적으로 삭제한다.', async () => {
91+
jest
92+
.spyOn(edgeRepository, 'delete')
93+
.mockResolvedValue({ affected: true } as any);
94+
jest.spyOn(edgeRepository, 'findOneBy').mockResolvedValue(new Edge());
95+
96+
await service.deleteEdge(1);
97+
98+
expect(edgeRepository.delete).toHaveBeenCalledWith(1);
99+
});
100+
101+
it('삭제할 엣지가 존재하지 않으면 EdgeNotFoundException을 throw한다.', async () => {
102+
jest
103+
.spyOn(edgeRepository, 'delete')
104+
.mockResolvedValue({ affected: false } as any);
105+
await expect(service.deleteEdge(1)).rejects.toThrow(
106+
EdgeNotFoundException,
107+
);
108+
});
109+
});
110+
111+
describe('findEdges', () => {
112+
it('존재하는 모든 엣지를 반환한다.', async () => {
113+
const node3 = {
114+
id: 3,
115+
x: 0,
116+
y: 0,
117+
title: 'Node Title',
118+
page: null,
119+
outgoingEdges: [],
120+
incomingEdges: [],
121+
} as Node;
122+
const node4 = {
123+
id: 4,
124+
x: 0,
125+
y: 0,
126+
title: 'Node Title',
127+
page: null,
128+
outgoingEdges: [],
129+
incomingEdges: [],
130+
} as Node;
131+
const node5 = {
132+
id: 5,
133+
x: 0,
134+
y: 0,
135+
title: 'Node Title',
136+
page: null,
137+
outgoingEdges: [],
138+
incomingEdges: [],
139+
} as Node;
140+
const node7 = {
141+
id: 7,
142+
x: 0,
143+
y: 0,
144+
title: 'Node Title',
145+
page: null,
146+
outgoingEdges: [],
147+
incomingEdges: [],
148+
} as Node;
149+
150+
const expectedEdgeList = [
151+
{
152+
id: 1,
153+
fromNode: node3,
154+
toNode: node5,
155+
} as Edge,
156+
{
157+
id: 2,
158+
fromNode: node3,
159+
toNode: node4,
160+
} as Edge,
161+
{
162+
id: 3,
163+
fromNode: node3,
164+
toNode: node7,
165+
} as Edge,
166+
];
167+
168+
jest.spyOn(edgeRepository, 'find').mockResolvedValue(expectedEdgeList);
169+
const result = await service.findEdges();
170+
expect(result).toEqual(expectedEdgeList);
171+
expect(edgeRepository.find).toHaveBeenCalledTimes(1);
172+
expect(edgeRepository.find).toHaveBeenCalledWith({
173+
relations: ['fromNode', 'toNode'],
174+
select: {
175+
id: true,
176+
fromNode: {
177+
id: true,
178+
},
179+
toNode: {
180+
id: true,
181+
},
182+
},
183+
});
184+
});
185+
186+
it('엣지가 없을 경우, 빈 배열을 던진다.', async () => {
187+
jest.spyOn(edgeRepository, 'find').mockResolvedValue([]);
188+
const result = await service.findEdges();
189+
expect(result).toEqual([]);
190+
});
191+
});
30192
});

0 commit comments

Comments
 (0)