Skip to content

Commit 18a3c4f

Browse files
test: auth service, auth controller 테스트 코드
1 parent 49b0cef commit 18a3c4f

File tree

4 files changed

+123
-15
lines changed

4 files changed

+123
-15
lines changed
Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,80 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22
import { AuthController } from './auth.controller';
33
import { AuthService } from './auth.service';
4-
4+
import { JwtService } from '@nestjs/jwt';
5+
import { InvalidTokenException } from '../exception/invalid.exception';
6+
import { LoginRequiredException } from '../exception/login.exception';
7+
// TODO: 테스트 코드 개선
58
describe('AuthController', () => {
6-
let controller: AuthController;
9+
let authController: AuthController;
710

811
beforeEach(async () => {
912
const module: TestingModule = await Test.createTestingModule({
1013
controllers: [AuthController],
1114
providers: [
15+
AuthService,
16+
JwtService,
1217
{
1318
provide: AuthService,
14-
useValue: {},
19+
useValue: {
20+
findUser: jest.fn(),
21+
createUser: jest.fn(),
22+
findUserById: jest.fn(),
23+
},
24+
},
25+
{
26+
provide: JwtService,
27+
useValue: {
28+
sign: jest.fn().mockReturnValue('test-token'),
29+
verify: jest.fn((token: string) => {
30+
if (token === 'invalid-token') {
31+
throw new InvalidTokenException();
32+
}
33+
return { sub: 1, provider: 'naver' };
34+
}),
35+
},
1536
},
1637
],
1738
}).compile();
1839

19-
controller = module.get<AuthController>(AuthController);
40+
authController = module.get<AuthController>(AuthController);
2041
});
2142

22-
it('should be defined', () => {
23-
expect(controller).toBeDefined();
43+
it('컨트롤러 클래스가 정상적으로 인스턴스화된다.', () => {
44+
expect(authController).toBeDefined();
45+
});
46+
47+
describe('getProfile', () => {
48+
it('JWT 토큰이 유효한 경우 profile을 return한다.', async () => {
49+
const req = {
50+
user: { sub: 1, email: '[email protected]', provider: 'naver' },
51+
} as any;
52+
const result = await authController.getProfile(req);
53+
expect(result).toEqual({
54+
message: '인증된 사용자 정보',
55+
user: req.user,
56+
});
57+
});
58+
59+
it('JWT 토큰이 유효가지 않은 경우 InvalidTokenException을 throw한다.', async () => {
60+
const req = {
61+
headers: { authorization: 'Bearer invalid-token' },
62+
user: undefined,
63+
} as any;
64+
try {
65+
await authController.getProfile(req);
66+
} catch (error) {
67+
expect(error).toBeInstanceOf(InvalidTokenException);
68+
}
69+
});
70+
71+
it('JWT 토큰이 없는 경우 LoginRequiredException을 throw한다.', async () => {
72+
const req = { headers: {}, user: undefined } as any;
73+
try {
74+
await authController.getProfile(req);
75+
} catch (error) {
76+
expect(error).toBeInstanceOf(LoginRequiredException);
77+
}
78+
});
2479
});
2580
});

apps/backend/src/auth/auth.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class AuthController {
5555
};
5656
}
5757

58-
// Example 1: 로그인한 사용자만 접근할 수 있는 엔드포인트
58+
// Example: 로그인한 사용자만 접근할 수 있는 엔드포인트
5959
// auth/profile
6060
@Get('profile')
6161
@UseGuards(JwtAuthGuard) // JWT 인증 검사
Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,78 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22
import { AuthService } from './auth.service';
33
import { UserRepository } from '../user/user.repository';
4+
import { CreateUserDto } from './dto/createUser.dto';
5+
import { User } from '../user/user.entity';
46

57
describe('AuthService', () => {
6-
let service: AuthService;
8+
let authService: AuthService;
9+
let userRepository: UserRepository;
710

811
beforeEach(async () => {
912
const module: TestingModule = await Test.createTestingModule({
1013
providers: [
1114
AuthService,
1215
{
1316
provide: UserRepository,
14-
useValue: {},
17+
useValue: {
18+
findOne: jest.fn(),
19+
create: jest.fn(),
20+
save: jest.fn(),
21+
},
1522
},
1623
],
1724
}).compile();
1825

19-
service = module.get<AuthService>(AuthService);
26+
authService = module.get<AuthService>(AuthService);
27+
userRepository = module.get<UserRepository>(UserRepository);
2028
});
2129

22-
it('should be defined', () => {
23-
expect(service).toBeDefined();
30+
it('서비스 클래스가 정상적으로 인스턴스화된다.', () => {
31+
expect(authService).toBeDefined();
32+
});
33+
34+
describe('findUser', () => {
35+
it('id에 해당하는 사용자를 찾아 성공적으로 반환한다.', async () => {
36+
const dto: CreateUserDto = {
37+
providerId: 'test-provider-id',
38+
provider: 'naver',
39+
40+
};
41+
const user = new User();
42+
jest.spyOn(userRepository, 'findOne').mockResolvedValue(user);
43+
44+
const result = await authService.findUser(dto);
45+
expect(result).toEqual(user);
46+
});
47+
48+
it('id에 해당하는 사용자가 없을 경우 null을 return한다.', async () => {
49+
jest.spyOn(userRepository, 'findOne').mockResolvedValue(null);
50+
const dto: CreateUserDto = {
51+
providerId: 'unknown-id',
52+
provider: 'naver',
53+
54+
};
55+
56+
const result = await authService.findUser(dto);
57+
expect(result).toBeNull();
58+
});
59+
});
60+
61+
describe('createUser', () => {
62+
it('사용자를 성공적으로 생성한다', async () => {
63+
const dto: CreateUserDto = {
64+
providerId: 'new-provider-id',
65+
provider: 'naver',
66+
67+
};
68+
const user = new User();
69+
jest.spyOn(userRepository, 'create').mockReturnValue(user);
70+
jest.spyOn(userRepository, 'save').mockResolvedValue(user);
71+
72+
const result = await authService.createUser(dto);
73+
expect(result).toEqual(user);
74+
expect(userRepository.create).toHaveBeenCalledWith(dto);
75+
expect(userRepository.save).toHaveBeenCalledWith(user);
76+
});
2477
});
2578
});

apps/backend/src/auth/guards/jwt-auth.guard.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
22
import { JwtService } from '@nestjs/jwt';
33
import { LoginRequiredException } from '../../exception/login.exception';
4-
import { InvalidTokenException } from 'src/exception/invalid.exception';
4+
import { InvalidTokenException } from '../../exception/invalid.exception';
55

66
@Injectable()
77
export class JwtAuthGuard implements CanActivate {
@@ -12,7 +12,7 @@ export class JwtAuthGuard implements CanActivate {
1212
const authorizationHeader = request.headers['authorization'];
1313

1414
if (!authorizationHeader) {
15-
console.log('Authorization header missing');
15+
// console.log('Authorization header missing');
1616
throw new LoginRequiredException();
1717
}
1818

@@ -25,7 +25,7 @@ export class JwtAuthGuard implements CanActivate {
2525
request.user = decodedToken;
2626
return true;
2727
} catch (error) {
28-
console.log('Invalid token');
28+
// console.log('Invalid token');
2929
throw new InvalidTokenException();
3030
}
3131
}

0 commit comments

Comments
 (0)