Skip to content

Commit

Permalink
[BE#475] 서비스 코드 리팩토링 및 테스트코드 수정 (#483)
Browse files Browse the repository at this point in the history
* refactor: categories service 리팩토링

- 사용되지 않는 변수 제거

* test: mate 테스트 코드 수정

- spyOn()을 이용하도록 테스트 코드 수정
- 서비스 로직에서 쿼리문 따로 함수로 분리

* refactor: 사용하지 않는 import 제거

* refactor: 학습 기록 서비스 로직 리팩토링

- db 쿼리 관련 로직 함수로 분리

* test: 테스트 코드 추가

- getPrimaryCategory()
- groupByCategory()

* test: 테스트 코드 수정

- user 서비스 테스트 코드 수정
- 컨트롤러 테스트 코드 삭제

* test: mate service 테스트 코드 수정

- jest.spyOn 사용하도록 수정

* test: auth service 모듈 임포트

* fix: 컨트롤러 복구

- 실수로 삭제한 컨트롤러 복구
  • Loading branch information
victolee0 authored Jan 9, 2024
1 parent 74067d8 commit 869aee1
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 178 deletions.
20 changes: 0 additions & 20 deletions BE/src/admin/admin.controller.spec.ts

This file was deleted.

20 changes: 0 additions & 20 deletions BE/src/auth/auth.controller.spec.ts

This file was deleted.

15 changes: 14 additions & 1 deletion BE/src/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
import { JwtService } from '@nestjs/jwt';
import { UsersService } from 'src/users/users.service';
import { MockUsersService } from '../../test/mock-service/mock-user-service';

describe('AuthService', () => {
let service: AuthService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService],
providers: [
AuthService,
{
provide: JwtService,
useValue: {},
},
{
provide: UsersService,
useClass: MockUsersService,
},
],
}).compile();

service = module.get<AuthService>(AuthService);
Expand Down
18 changes: 0 additions & 18 deletions BE/src/categories/categories.controller.spec.ts

This file was deleted.

2 changes: 1 addition & 1 deletion BE/src/categories/categories.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export class CategoriesService {
);
}

const result = await this.categoriesRepository.delete(id);
await this.categoriesRepository.delete(id);
}

entityToDto(category: Categories): CategoryDto {
Expand Down
18 changes: 0 additions & 18 deletions BE/src/mates/mates.controller.spec.ts

This file was deleted.

137 changes: 121 additions & 16 deletions BE/src/mates/mates.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,34 @@ import { Test, TestingModule } from '@nestjs/testing';
import { MatesService } from './mates.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Mates } from './mates.entity';
import { MockMatesRepository } from '../../test/mock-repo/mock-mates-repo';
import { UsersModel } from 'src/users/entity/users.entity';
import { MockUsersRepository } from '../../test/mock-repo/mock-user-repo';
import { StudyLogsService } from 'src/study-logs/study-logs.service';
import { MockStudyLogsService } from '../../test/mock-service/mock-study-logs-service';
import { ConfigService } from '@nestjs/config';
import { RedisService } from 'src/common/redis.service';
import { MockRedisService } from '../../test/mock-service/mock-redis-service';
import { BadRequestException, NotFoundException } from '@nestjs/common';
import { MockConfigService } from '../../test/mock-service/mock-config-service';
import { Repository } from 'typeorm';

describe('MatesService', () => {
let service: MatesService;
let repository: Repository<Mates>;
let redisService: RedisService;
let studyLogsService: StudyLogsService;
let usersRepository: Repository<UsersModel>;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
MatesService,
{
provide: getRepositoryToken(Mates),
useClass: MockMatesRepository,
useClass: Repository,
},
{
provide: getRepositoryToken(UsersModel),
useClass: MockUsersRepository,
useClass: Repository,
},
{
provide: RedisService,
Expand All @@ -44,6 +47,12 @@ describe('MatesService', () => {
}).compile();

service = module.get<MatesService>(MatesService);
redisService = module.get<RedisService>(RedisService);
studyLogsService = module.get<StudyLogsService>(StudyLogsService);
repository = module.get<Repository<Mates>>(getRepositoryToken(Mates));
usersRepository = module.get<Repository<UsersModel>>(
getRepositoryToken(UsersModel),
);
});

it('should be defined', () => {
Expand All @@ -58,6 +67,23 @@ describe('MatesService', () => {
} as UsersModel;
describe('.addMate()', () => {
it('유효한 데이터가 주어지면 성공적으로 친구 추가를 해야한다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce({
id: 3,
nickname: '어린콩3',
image_url: null,
} as UsersModel);
jest.spyOn(repository, 'count').mockResolvedValueOnce(1);
jest.spyOn(repository, 'findOne').mockResolvedValueOnce(null);
jest.spyOn(repository, 'create').mockResolvedValueOnce({
id: 2,
follower_id: { id: 1 },
following_id: { id: 3 },
} as never);
jest.spyOn(repository, 'save').mockResolvedValueOnce({
id: 2,
follower_id: { id: 1 } as UsersModel,
following_id: { id: 3 } as UsersModel,
});
const result = await service.addMate(user, '어린콩3');
expect(result).toStrictEqual({
id: 2,
Expand All @@ -66,21 +92,48 @@ describe('MatesService', () => {
});
});

it.todo('친구는 최대 10명까지 추가할 수 있다.');
it('친구는 최대 10명까지 추가할 수 있다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce({
id: 3,
nickname: '어린콩3',
image_url: null,
} as UsersModel);
jest.spyOn(repository, 'count').mockResolvedValueOnce(10);
expect(service.addMate(user, '어린콩3')).rejects.toThrow(
BadRequestException,
);
});

it('자신을 친구 추가 할 수 없다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce({
id: 1,
nickname: '어린콩',
image_url: null,
} as UsersModel);
expect(service.addMate(user, '어린콩')).rejects.toThrow(
BadRequestException,
);
});

it('존재하지 않는 유저를 친구 추가 할 수 없다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce(null);
expect(service.addMate(user, '어린콩4')).rejects.toThrow(
NotFoundException,
);
});

it('이미 친구 관계인 유저에게 친구 신청을 할 수 없다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce({
id: 3,
nickname: '어린콩3',
image_url: null,
} as UsersModel);
jest.spyOn(repository, 'count').mockResolvedValueOnce(1);
jest.spyOn(repository, 'findOne').mockResolvedValueOnce({
id: 1,
follower_id: { id: 1 } as UsersModel,
following_id: { id: 3 } as UsersModel,
});
expect(service.addMate(user, '어린콩2')).rejects.toThrow(
BadRequestException,
);
Expand All @@ -89,21 +142,45 @@ describe('MatesService', () => {

describe('.deleteMate()', () => {
it('유효한 데이터가 주어지면 성공적으로 친구 삭제를 해야한다.', async () => {
const data = {
id: 1,
follower_id: { id: 1 } as UsersModel,
following_id: { id: 2 } as UsersModel,
};
jest
.spyOn(usersRepository, 'findOne')
.mockResolvedValueOnce({ id: 2 } as UsersModel);
jest.spyOn(repository, 'delete').mockResolvedValueOnce(data as never);
const result = await service.deleteMate(user, 2);
expect(result).toStrictEqual(undefined);
});

it('존재하지 않는 유저를 친구 삭제 할 수 없다.', () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce(null);
expect(service.deleteMate(user, 100)).rejects.toThrow(NotFoundException);
});

it('친구 관계가 아닌 유저를 친구 삭제 할 수 없다.', () => {
jest
.spyOn(usersRepository, 'findOne')
.mockResolvedValueOnce({ id: 2 } as UsersModel);
jest.spyOn(repository, 'delete').mockResolvedValueOnce(null);
expect(service.deleteMate(user, 3)).rejects.toThrow(NotFoundException);
});
});

describe('.getMatesStatus()', () => {
it('유효한 데이터가 주어지면 성공적으로 친구 상태를 가져온다.', async () => {
jest.spyOn(repository, 'find').mockResolvedValueOnce([
{
id: 1,
follower_id: { id: 1 } as UsersModel,
following_id: { id: 2 } as UsersModel,
},
]);
jest
.spyOn(redisService, 'hget')
.mockResolvedValueOnce('2023-11-29 16:00:00');
const result = await service.getMatesStatus(1);
expect(result).toStrictEqual([
{ id: 2, started_at: '2023-11-29 16:00:00' },
Expand All @@ -113,7 +190,15 @@ describe('MatesService', () => {

describe('.getMates()', () => {
it('유효한 데이터가 주어지면 성공적으로 친구들을 가져온다.', async () => {
const result = await service.getMates(1, '2023-11-29');
jest
.spyOn(service, 'getMatesStudyTime')
.mockResolvedValueOnce([
{ id: 2, nickname: '어린콩2', total_time: 825 },
]);
jest
.spyOn(redisService, 'hget')
.mockResolvedValueOnce('2023-11-29 16:00:00');
const result = await service.getMates(1, '2023-11-29', '09:00');
expect(result).toStrictEqual([
{
id: 2,
Expand All @@ -125,13 +210,23 @@ describe('MatesService', () => {
]);
});
it('친구가 없는 유저는 빈 배열을 가져온다.', async () => {
const result = await service.getMates(3, '2023-11-29');
jest.spyOn(service, 'getMatesStudyTime').mockResolvedValueOnce([]);
const result = await service.getMates(3, '2023-11-29', '09:00');
expect(result).toStrictEqual([]);
});
});

describe('.getMateAndMyStats()', () => {
it('유효한 데이터가 주어지면 성공적으로 친구들의 학습시간과 내 학습시간을 가져온다.', async () => {
jest
.spyOn(studyLogsService, 'calculateTotalTimes')
.mockResolvedValueOnce([0, 0, 0, 0, 0, 0, 827]);
jest
.spyOn(studyLogsService, 'calculateTotalTimes')
.mockResolvedValueOnce([0, 0, 0, 0, 0, 0, 825]);
jest
.spyOn(studyLogsService, 'getPrimaryCategory')
.mockResolvedValueOnce(null);
const result = await service.getMateAndMyStats(1, 2, '2023-11-29');
expect(result).toStrictEqual({
my_daily_data: [0, 0, 0, 0, 0, 0, 827],
Expand All @@ -141,17 +236,14 @@ describe('MatesService', () => {
});
});

it('학습 시간이 존재하지 않는 경우 모든 값이 0인 배열을 반환한다.', async () => {
const result = await service.getMateAndMyStats(1, 2, '2023-12-29');
expect(result).toStrictEqual({
my_daily_data: [0, 0, 0, 0, 0, 0, 0],
following_daily_data: [0, 0, 0, 0, 0, 0, 0],
following_primary_category: null,
});
});

describe('.findMate()', () => {
it('유효한 데이터가 주어지면 20000코드를 준다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce({
id: 3,
nickname: '어린콩3',
image_url: null,
} as UsersModel);
jest.spyOn(repository, 'findOne').mockResolvedValueOnce(null);
const result = await service.findMate(user, '어린콩3');
expect(result).toStrictEqual({
statusCode: 20000,
Expand All @@ -160,6 +252,8 @@ describe('MatesService', () => {
});

it('자신을 검색하면 20001코드를 준다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce(user);
jest.spyOn(repository, 'findOne').mockResolvedValueOnce(null);
const result = await service.findMate(user, '어린콩');
expect(result).toStrictEqual({
statusCode: 20001,
Expand All @@ -168,6 +262,16 @@ describe('MatesService', () => {
});

it('이미 친구 관계인 유저를 검색하면 20002코드를 준다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce({
id: 2,
nickname: '어린콩2',
image_url: null,
} as UsersModel);
jest.spyOn(repository, 'findOne').mockResolvedValueOnce({
id: 1,
follower_id: { id: 1 } as UsersModel,
following_id: { id: 2 } as UsersModel,
});
const result = await service.findMate(user, '어린콩2');
expect(result).toStrictEqual({
statusCode: 20002,
Expand All @@ -176,6 +280,7 @@ describe('MatesService', () => {
});

it('존재하지 않는 유저를 검색하면 에러를 던진다.', async () => {
jest.spyOn(usersRepository, 'findOne').mockResolvedValueOnce(null);
expect(service.findMate(user, '어린콩4')).rejects.toThrow(
NotFoundException,
);
Expand Down
Loading

0 comments on commit 869aee1

Please sign in to comment.