카테고리 없음

15주차 (2)

jaeoun0238 2025. 2. 4. 22:46

드디어 모든 파일을 다 합치고 테스트 코드를 작성해 보기로 했습니다.

jest를 사용하고 spec파일에 테스트 코드를 작성해 보았습니다.

처음 jest를 써보는 거라 오류가 많이 나고 있는 중입니다.. ㅠ

 

cardcontroller.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { CardController } from './card.controller';
import { CardService } from './card.service';
import { CreateCardDto } from './dto/create-card.dto';
import { User } from 'src/user/entities/user.entity';
import { UpdateCardDto } from './dto/update-card.dto';

describe('CardController', () => {
  let controller: CardController;
  let service: CardService;

  const mockCardService = {
    createCard: jest.fn(),
    findCards: jest.fn(),
    findCard: jest.fn(),
    updateCardOrder: jest.fn(),
    deleteCard: jest.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [CardController],
      providers: [{ provide: CardService, useValue: mockCardService }],
    }).compile();

    controller = module.get<CardController>(CardController);
    service = module.get<CardService>(CardService);
  });
  afterEach(() => {
    jest.clearAllMocks();
  });

  describe('create', () => {
    it('카드 생성 테스트', async () => {
      const user: User = { id: 1, email: 'asfd1234@naver.com' } as User;
      const columnId = 1;

      const createCardDto: CreateCardDto = {
        title: '카드 제목',
        content: '카드 내용',
      };

      const result = { id: 1, column: 1, title: '카드 제목', position: 1 };

      mockCardService.createCard.mockResolvedValue(result);

      const response = await controller.createCard(
        user,
        columnId,
        createCardDto,
      );

      expect(mockCardService.createCard).toHaveBeenCalledWith(
        1,
        1,
        createCardDto, // 컨트롤러에 리턴값이 3개였으니까 3개 다줘야함! 받는값을 넣어줘야해요!
      );
      expect(response).toEqual(result);
    });
  });

  describe('findCards', () => {
    it('모든 카드를 가져오는 테스트', async () => {
      const user: User = { id: 1, email: 'asfd1234@naver.com' } as User;
      const columnId = 1;
      const cards = [
        { id: 1, title: '첫 번째 카드', content: '내용1' },
        { id: 2, title: '두 번째 카드', content: '내용2' },
      ];

      mockCardService.findCards.mockResolvedValue(cards);

      const response = await controller.findCards(user, columnId);

      expect(mockCardService.findCards).toHaveBeenCalledWith(1, 1);
      expect(response).toEqual(cards);
    });
  });

  describe('findCard', () => {
    it('특정 카드를 가져오는 테스트', async () => {
      const user: User = { id: 1, email: 'asfd1234@naver.com' } as User;
      const columnId = 1;
      const cardId = 1;
      const card = { id: 1, title: '카드 제목', content: '카드 내용' };

      mockCardService.findCard.mockResolvedValue(card);

      const response = await controller.findCard(user, columnId, cardId);

      expect(mockCardService.findCard).toHaveBeenCalledWith(1, 1, 1);
      expect(response).toEqual(card);
    });
  });

  describe('update', () => {
    it('카드를 업데이트하는 테스트', async () => {
      const user: User = { id: 1, email: 'asfd1234@naver.com' } as User;
      const columnId = 1;
      const cardId = 1;
      const targetCardId = 2; // 이동 대상 카드 ID

      const updateCardDto: UpdateCardDto = {
        title: '새로운 제목',
        content: '새로운 내용',
        cardPosition: 1,
      };

      const updatedCard = {
        id: 1,
        title: '새로운 제목',
        content: '새로운 내용',
      };

      mockCardService.updateCardOrder.mockResolvedValue(updatedCard);

      const response = await controller.update(
        user,
        columnId,
        cardId,
        targetCardId,
      );

      expect(mockCardService.updateCardOrder).toHaveBeenCalledWith(1, 1, 1, 2);
      expect(response).toEqual(updatedCard);
    });
  });

  describe('deleteCard', () => {
    it('카드를 삭제하는 테스트', async () => {
      const user: User = { id: 1, email: 'asfd1234@naver.com' } as User;
      const cardId = 1;
      const columnId = 1;

      // 컨트롤러에서 실제 반환하는 값과 일치하도록 수정
      mockCardService.deleteCard.mockResolvedValue({
        message: '카드가 삭제되었습니다',
      });

      const response = await controller.deleteCard(user, columnId, cardId);

      // 호출된 인자 검증
      expect(mockCardService.deleteCard).toHaveBeenCalledWith(1, 1, 1);
      // 반환값이 실제 서비스의 반환값과 일치하는지 확인
      expect(response).toEqual({ message: '카드가 삭제되었습니다' });
    });
  });

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

 

제대로 작동하는것을 확인했습니다. 

문제는 service파일에서 생겼는데

 

card.servoce.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { CardService } from './card.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Card } from './entities/card.entity';
import { Member } from 'src/member/entities/member.entity';
import { Board } from 'src/board/entities/board.entity';
import { ColumnEntity } from 'src/column/entities/column.entity';
import { Repository } from 'typeorm';
import { CreateCardDto } from './dto/create-card.dto';
import { UpdateCardDto } from './dto/update-card.dto';
import { LexoRank } from 'lexorank';

describe('CardService', () => {
  let service: CardService;
  let cardRepository: Repository<Card>;
  let memberRepository: Repository<Member>;
  let boardRepository: Repository<Board>;
  let columnRepository: Repository<ColumnEntity>;

  const mockCardRepository = {
    create: jest.fn(),
    save: jest.fn(),
    find: jest.fn(),
    findOne: jest.fn(),
    update: jest.fn(),
    delete: jest.fn(),
  };

  const mockMemberRepository = {
    findOne: jest.fn(),
  };

  const mockBoardRepository = {
    findOne: jest.fn(),
  };

  const mockColumnRepository = {
    findOne: jest.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        CardService,
        { provide: getRepositoryToken(Card), useValue: mockCardRepository },
        { provide: getRepositoryToken(Member), useValue: mockMemberRepository },
        { provide: getRepositoryToken(Board), useValue: mockBoardRepository },
        {
          provide: getRepositoryToken(ColumnEntity),
          useValue: mockColumnRepository,
        },
      ],
    }).compile();

    service = module.get<CardService>(CardService);
    cardRepository = module.get<Repository<Card>>(getRepositoryToken(Card));
    memberRepository = module.get<Repository<Member>>(
      getRepositoryToken(Member),
    );
    boardRepository = module.get<Repository<Board>>(getRepositoryToken(Board));
    columnRepository = module.get<Repository<ColumnEntity>>(
      getRepositoryToken(ColumnEntity),
    );
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('createCard', () => {
    it('should create a new card', async () => {
      const userId = 1;
      const columnId = 1;
      const createCardDto: CreateCardDto = {
        title: 'New Card',
        content: 'Card Content',
      };

      const column = { id: columnId, board: { id: 99 } };
      const member = { id: 10, userId, boardId: column.board.id };
      const newCard = {
        id: 1,
        columnId,
        content: createCardDto.content,
        lexo: LexoRank.middle().toString(),
        memberId: member.id,
        title: createCardDto.title,
      };

      mockColumnRepository.findOne.mockResolvedValue(column);
      mockMemberRepository.findOne.mockResolvedValue(member);
      mockCardRepository.create.mockReturnValue(newCard);
      mockCardRepository.save.mockResolvedValue(newCard);

      const result = await service.createCard(userId, columnId, createCardDto);
      expect(result).toEqual(newCard);
    });
  });

  describe('findCards', () => {
    it('should return all cards in a column', async () => {
      const userId = 1;
      const columnId = 1;
      const cards = [
        { id: 1, title: 'Card 1', content: 'Content 1', columnId },
        { id: 2, title: 'Card 2', content: 'Content 2', columnId },
      ];

      mockCardRepository.find.mockResolvedValue(cards);

      const result = await service.findCards(userId, columnId);
      expect(result).toEqual(cards);
    });
  });

  describe('findCard', () => {
    it('should return a specific card', async () => {
      const userId = 1;
      const columnId = 1;
      const cardId = 1;
      const card = {
        id: cardId,
        title: 'Card 1',
        content: 'Content 1',
        columnId: 1,
      };

      mockCardRepository.findOne.mockResolvedValue(card);

      const result = await service.findCard(userId, columnId, cardId);
      expect(result).toEqual(card);
    });
  });

  describe('updateCardOrder', () => {
    it('should update card order', async () => {
      const userId = 1;
      const columnId = 1;
      const cardId = 1;
      const targetCardId = 2;

      const column = { id: columnId, board: { id: 99 } };
      const cards = [
        { id: 1, lexo: LexoRank.middle().toString() },
        { id: 2, lexo: LexoRank.middle().genNext().toString() },
      ];
      const targetCard = {
        id: targetCardId,
        lexo: LexoRank.middle().genNext().toString(),
      };

      const updatedCard = {
        id: cardId,
        lexo: LexoRank.parse(targetCard.lexo).genNext().toString(),
      };

      mockColumnRepository.findOne.mockResolvedValue(column);
      mockMemberRepository.findOne.mockResolvedValue({
        boardId: column.board.id,
        userId,
      });
      mockCardRepository.find.mockResolvedValue(cards);
      mockCardRepository.findOne.mockResolvedValue(targetCard);
      mockCardRepository.update.mockResolvedValue(updatedCard);

      const result = await service.updateCardOrder(
        userId,
        columnId,
        cardId,
        targetCardId,
      );
      expect(result).toEqual(updatedCard);
    });
  });

  describe('deleteCard', () => {
    it('should delete a card', async () => {
      const userId = 1;
      const cardId = 1;
      const columnId = 1;
      const column = { id: columnId, board: { id: 99 } };

      mockColumnRepository.findOne.mockResolvedValue(column);
      mockMemberRepository.findOne.mockResolvedValue({
        boardId: column.board.id,
        userId,
      });
      mockCardRepository.delete.mockResolvedValue({ affected: 1 });

      const result = await service.deleteCard(userId, cardId, columnId);
      expect(result).toEqual({ message: '카드가 삭제되었습니다' });
    });
  });
});

이러한 오류가 발생하여 방법을 찾아보고 있습니다.ㅜㅜ

제 생각엔 result에서 제대로 받아오지 못하고 있는것 같은데 값을 입력해줘도 소용이 없어서 다시 해볼생각입니다..!