Skip to content

Commit

Permalink
test: jest-mock-extended 제거
Browse files Browse the repository at this point in the history
PrismaService를 DeepMockProxy 등을 사용하지 않고 필요한 함수만 Mocking한다.
  • Loading branch information
Conut-1 committed Sep 4, 2024
1 parent 2c6fdde commit e1d9488
Show file tree
Hide file tree
Showing 12 changed files with 777 additions and 800 deletions.
1,035 changes: 468 additions & 567 deletions nestjs-BE/server/package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion nestjs-BE/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"jest-mock-extended": "^3.0.7",
"prettier": "^3.0.0",
"prisma": "^5.6.0",
"source-map-support": "^0.5.21",
Expand Down
94 changes: 57 additions & 37 deletions nestjs-BE/server/src/auth/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
import { PrismaService } from '../prisma/prisma.service';
import { DeepMockProxy, mockDeep } from 'jest-mock-extended';
import { PrismaClient, RefreshToken, User } from '@prisma/client';
import { RefreshToken, User } from '@prisma/client';
import { AuthService } from './auth.service';
import { UsersService } from '../users/users.service';
import { RefreshTokensService } from './refresh-tokens.service';
Expand All @@ -11,37 +9,47 @@ import { BadRequestException, NotFoundException } from '@nestjs/common';

describe('AuthController', () => {
let controller: AuthController;
let refreshTokensService: DeepMockProxy<RefreshTokensService>;
let usersService: DeepMockProxy<UsersService>;
let authService: DeepMockProxy<AuthService>;
let refreshTokensService: RefreshTokensService;
let usersService: UsersService;
let authService: AuthService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
providers: [
AuthService,
PrismaService,
UsersService,
ProfilesService,
RefreshTokensService,
{
provide: AuthService,
useValue: {
getKakaoAccount: jest.fn(),
login: jest.fn(),
renewAccessToken: jest.fn(),
},
},
{
provide: UsersService,
useValue: {
findUserByEmailAndProvider: jest.fn(),
createUser: jest.fn(),
},
},
{
provide: ProfilesService,
useValue: {
createProfile: jest.fn(),
},
},
{
provide: RefreshTokensService,
useValue: { deleteRefreshToken: jest.fn() },
},
],
})
.overrideProvider(AuthService)
.useValue(mockDeep<AuthService>())
.overrideProvider(PrismaService)
.useValue(mockDeep<PrismaClient>())
.overrideProvider(UsersService)
.useValue(mockDeep<UsersService>())
.overrideProvider(ProfilesService)
.useValue(mockDeep<ProfilesService>())
.overrideProvider(RefreshTokensService)
.useValue(mockDeep<RefreshTokensService>())
.compile();
}).compile();

controller = module.get<AuthController>(AuthController);
refreshTokensService = module.get(RefreshTokensService);
authService = module.get(AuthService);
usersService = module.get(UsersService);
refreshTokensService =
module.get<RefreshTokensService>(RefreshTokensService);
authService = module.get<AuthService>(AuthService);
usersService = module.get<UsersService>(UsersService);
});

it('kakaoLogin user have been logged in', async () => {
Expand All @@ -51,11 +59,13 @@ describe('AuthController', () => {
refresh_token: 'refresh token',
access_token: 'access token',
};
authService.getKakaoAccount.mockResolvedValue(kakaoUserAccountMock);
usersService.findUserByEmailAndProvider.mockResolvedValue({
jest
.spyOn(authService, 'getKakaoAccount')
.mockResolvedValue(kakaoUserAccountMock);
jest.spyOn(usersService, 'findUserByEmailAndProvider').mockResolvedValue({
uuid: 'user uuid',
} as User);
authService.login.mockResolvedValue(tokenMock);
jest.spyOn(authService, 'login').mockResolvedValue(tokenMock);

const response = controller.kakaoLogin(requestMock);

Expand All @@ -74,9 +84,13 @@ describe('AuthController', () => {
refresh_token: 'refresh token',
access_token: 'access token',
};
authService.getKakaoAccount.mockResolvedValue(kakaoUserAccountMock);
usersService.createUser.mockResolvedValue({ uuid: 'user uuid' } as User);
authService.login.mockResolvedValue(tokenMock);
jest
.spyOn(authService, 'getKakaoAccount')
.mockResolvedValue(kakaoUserAccountMock);
jest
.spyOn(usersService, 'createUser')
.mockResolvedValue({ uuid: 'user uuid' } as User);
jest.spyOn(authService, 'login').mockResolvedValue(tokenMock);

const response = controller.kakaoLogin(requestMock);

Expand All @@ -90,7 +104,7 @@ describe('AuthController', () => {

it('kakaoLogin kakao login fail', async () => {
const requestMock = { kakaoUserId: 0 };
authService.getKakaoAccount.mockResolvedValue(null);
jest.spyOn(authService, 'getKakaoAccount').mockResolvedValue(null);

const response = controller.kakaoLogin(requestMock);

Expand All @@ -99,7 +113,9 @@ describe('AuthController', () => {

it('renewAccessToken respond new access token', async () => {
const requestMock = { refresh_token: 'refresh token' };
authService.renewAccessToken.mockResolvedValue('new access token');
jest
.spyOn(authService, 'renewAccessToken')
.mockResolvedValue('new access token');

const response = controller.renewAccessToken(requestMock);

Expand All @@ -112,7 +128,7 @@ describe('AuthController', () => {

it('renewAccessToken received expired token', async () => {
const requestMock = { refresh_token: 'refresh token' };
authService.renewAccessToken.mockRejectedValue(new Error());
jest.spyOn(authService, 'renewAccessToken').mockRejectedValue(new Error());

const response = controller.renewAccessToken(requestMock);

Expand All @@ -122,7 +138,9 @@ describe('AuthController', () => {
it('logout received token deleted', async () => {
const requestMock = { refresh_token: 'refresh token' };
const token = {} as RefreshToken;
refreshTokensService.deleteRefreshToken.mockResolvedValue(token);
jest
.spyOn(refreshTokensService, 'deleteRefreshToken')
.mockResolvedValue(token);

const response = controller.logout(requestMock);

Expand All @@ -134,7 +152,9 @@ describe('AuthController', () => {

it('logout received token not found', async () => {
const requestMock = { refresh_token: 'bad refresh token' };
refreshTokensService.deleteRefreshToken.mockResolvedValue(null);
jest
.spyOn(refreshTokensService, 'deleteRefreshToken')
.mockResolvedValue(null);

const response = controller.logout(requestMock);

Expand Down
44 changes: 23 additions & 21 deletions nestjs-BE/server/src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
import { DeepMockProxy, mockDeep } from 'jest-mock-extended';
import { PrismaClient, RefreshToken } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { RefreshToken } from '@prisma/client';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { RefreshTokensService } from './refresh-tokens.service';

const fetchSpy = jest.spyOn(global, 'fetch');

describe('AuthService', () => {
let service: AuthService;
let prisma: DeepMockProxy<PrismaClient>;
let jwtService: DeepMockProxy<JwtService>;
let refreshTokensService: DeepMockProxy<RefreshTokensService>;
let jwtService: JwtService;
let refreshTokensService: RefreshTokensService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [JwtModule],
providers: [AuthService, PrismaService, RefreshTokensService],
providers: [
AuthService,
{
provide: RefreshTokensService,
useValue: {
createRefreshToken: jest.fn(),
findRefreshToken: jest.fn(),
},
},
],
})
.overrideProvider(PrismaService)
.useValue(mockDeep<PrismaClient>())
.overrideProvider(JwtService)
.useValue(mockDeep<JwtService>())
.overrideProvider(RefreshTokensService)
.useValue(mockDeep<RefreshToken>())
.useValue({ signAsync: jest.fn(), verify: jest.fn() })
.compile();

service = module.get<AuthService>(AuthService);
prisma = module.get(PrismaService);
jwtService = module.get(JwtService);
refreshTokensService = module.get(RefreshTokensService);
jwtService = module.get<JwtService>(JwtService);
refreshTokensService =
module.get<RefreshTokensService>(RefreshTokensService);
});

afterEach(() => {
fetchSpy.mockRestore();
});

it('login success', async () => {
jwtService.signAsync.mockResolvedValue('access token');
refreshTokensService.createRefreshToken.mockResolvedValue({
jest.spyOn(jwtService, 'signAsync').mockResolvedValue('access token');
jest.spyOn(refreshTokensService, 'createRefreshToken').mockResolvedValue({
token: 'refresh token',
} as unknown as RefreshToken);

Expand All @@ -52,9 +54,9 @@ describe('AuthService', () => {
});

it('renewAccessToken success', async () => {
jwtService.verify.mockReturnValue({});
jwtService.signAsync.mockResolvedValue('access token');
refreshTokensService.findRefreshToken.mockResolvedValue({
jest.spyOn(jwtService, 'verify').mockReturnValue({});
jest.spyOn(jwtService, 'signAsync').mockResolvedValue('access token');
jest.spyOn(refreshTokensService, 'findRefreshToken').mockResolvedValue({
user_id: 'user uuid',
} as RefreshToken);

Expand All @@ -64,7 +66,7 @@ describe('AuthService', () => {
});

it('renewAccessToken fail', async () => {
jwtService.verify.mockImplementation(() => {
jest.spyOn(jwtService, 'verify').mockImplementation(() => {
throw new Error();
});

Expand Down
60 changes: 36 additions & 24 deletions nestjs-BE/server/src/auth/refresh-tokens.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RefreshTokensService } from './refresh-tokens.service';
import { DeepMockProxy, mockDeep } from 'jest-mock-extended';
import { PrismaClient } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';
Expand All @@ -10,21 +8,31 @@ jest.useFakeTimers();

describe('RefreshTokensService', () => {
let service: RefreshTokensService;
let prisma: DeepMockProxy<PrismaClient>;
let prisma: PrismaService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [JwtModule],
providers: [RefreshTokensService, PrismaService],
providers: [
RefreshTokensService,
{
provide: PrismaService,
useValue: {
refreshToken: {
findUnique: jest.fn(),
create: jest.fn(),
delete: jest.fn(),
},
},
},
],
})
.overrideProvider(PrismaService)
.useValue(mockDeep<PrismaClient>())
.overrideProvider(JwtService)
.useValue(mockDeep<JwtService>())
.useValue({ sign: jest.fn() })
.compile();

service = module.get<RefreshTokensService>(RefreshTokensService);
prisma = module.get(PrismaService);
prisma = module.get<PrismaService>(PrismaService);
});

afterEach(() => {
Expand All @@ -48,15 +56,15 @@ describe('RefreshTokensService', () => {
expiry_date: service.getExpiryDate(),
user_id: 'UserId',
};
prisma.refreshToken.findUnique.mockResolvedValue(testToken);
jest.spyOn(prisma.refreshToken, 'findUnique').mockResolvedValue(testToken);

const token = service.findRefreshToken(testToken.token);

await expect(token).resolves.toEqual(testToken);
});

it('findRefreshToken not found token', async () => {
prisma.refreshToken.findUnique.mockResolvedValue(null);
jest.spyOn(prisma.refreshToken, 'findUnique').mockResolvedValue(null);

const token = service.findRefreshToken('Token');

Expand All @@ -70,20 +78,22 @@ describe('RefreshTokensService', () => {
expiry_date: service.getExpiryDate(),
user_id: 'userId',
};
prisma.refreshToken.create.mockResolvedValue(testToken);
jest.spyOn(prisma.refreshToken, 'create').mockResolvedValue(testToken);

const token = service.createRefreshToken('userId');

await expect(token).resolves.toEqual(testToken);
});

it('createUser user already exists', async () => {
prisma.refreshToken.create.mockRejectedValue(
new PrismaClientKnownRequestError(
'Unique constraint failed on the constraint: `RefreshToken_token_key`',
{ code: 'P2025', clientVersion: '' },
),
);
jest
.spyOn(prisma.refreshToken, 'create')
.mockRejectedValue(
new PrismaClientKnownRequestError(
'Unique constraint failed on the constraint: `RefreshToken_token_key`',
{ code: 'P2025', clientVersion: '' },
),
);

const token = service.createRefreshToken('userId');

Expand All @@ -97,20 +107,22 @@ describe('RefreshTokensService', () => {
expiry_date: service.getExpiryDate(),
user_id: 'userId',
};
prisma.refreshToken.delete.mockResolvedValue(testToken);
jest.spyOn(prisma.refreshToken, 'delete').mockResolvedValue(testToken);

const token = service.deleteRefreshToken(testToken.token);

await expect(token).resolves.toEqual(testToken);
});

it('deleteRefreshToken not found', async () => {
prisma.refreshToken.delete.mockRejectedValue(
new PrismaClientKnownRequestError(
'An operation failed because it depends on one or more records that were required but not found. Record to update not found.',
{ code: 'P2025', clientVersion: '' },
),
);
jest
.spyOn(prisma.refreshToken, 'delete')
.mockRejectedValue(
new PrismaClientKnownRequestError(
'An operation failed because it depends on one or more records that were required but not found. Record to delete not found.',
{ code: 'P2025', clientVersion: '' },
),
);

const token = service.deleteRefreshToken('Token');

Expand Down
Loading

0 comments on commit e1d9488

Please sign in to comment.