Backend/Spring & JPA

[Spring] Backend 테스트 코드 작성 법 (feat.JPA)

JOKUN 2022. 10. 19. 21:19

 

 

백엔드 코드를 작성하다 보면 프론트엔드 쪽에서 아직 연결할 UI가 완성되지 않았을 수도 있고,  프론트엔드와 연결하기 전에 작성한 코드가 제대로 기능 구현이 됐는지 확인할 필요가 있다.

백엔드 안에서 부분 테스트를 통하여 프론트 UI 없이도 기능이 제대로 구현되었는지 검증할 수 있다.

 

학급과 학생 엔티티가 있다고 가정할 시에

Entity

ClassRoom

package com.example.demo.entity.test;


import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@Entity
@NoArgsConstructor
public class ClassRoom {

    @Id
    @Column(name = "class_room_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long classRoomId;

    private String roomName;

    public ClassRoom (String roomName) {
        this.roomName = roomName;
    }
}

 

TestStudent

package com.example.demo.entity.test;

import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Data
@Entity
@NoArgsConstructor
public class TestStudent {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long studentId;

    private String name;

    @ManyToOne
    @JoinColumn(name = "class_room_id")
    private ClassRoom classRoom;

    public TestStudent (String name) {
        this.name = name;
    }

    public void setClassRoom(ClassRoom classRoom) {
        this.classRoom = classRoom;
    }
}
@ManyToOne과 JoinColums에 대해서는 다른 글에서 자세하게 설명! (추후 링크 첨부 예정)

그리고 TestStudent 클래스에서는 setClassRoom이라는 메서드를 따로 만들어 주었는데
만들어진 ClassRoom정보를 setting해야하기 때문!
test-StudentTestCase에서 이 부분을 이해하면 된다. 

 

Repository

ClassRoomRepository

package com.example.demo.repository.test;

import com.example.demo.entity.test.ClassRoom;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ClassRoomRepository extends JpaRepository<ClassRoom, Long> {
}

 

TestStudentRepository

package com.example.demo.repository.test;

import com.example.demo.entity.test.TestStudent;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;
import java.util.Optional;

public interface TestStudentRepository extends JpaRepository<TestStudent, Long> {

    @Query("select ts from TestStudent ts join ts.classRoom cr where cr.roomName = :roomName")
    Optional<TestStudent> findTestStudentByRoomName (String roomName);

    @Query("select ts from TestStudent ts join ts.classRoom cr where cr.roomName = :roomName")
    List<TestStudent> findTestStudentListByRoomName (String roomName);
}

 

 

Test

프로젝트에는 main과 test가 있는데 이 test 폴더에서 테스트 코드를 작성하고 확인할 수 있다.

StudentTestCase

package com.example.demo;


import com.example.demo.entity.test.ClassRoom;
import com.example.demo.entity.test.TestStudent;
import com.example.demo.repository.test.ClassRoomRepository;
import com.example.demo.repository.test.TestStudentRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Optional;

@SpringBootTest
public class StudentTestCase {

    @Autowired
    private TestStudentRepository studentRepository;

    @Autowired
    private ClassRoomRepository classRoomRepository;

    /** 등록 Test */
    @Test
    void registerStudentTest() {
        //ClassRoom classRoom = new ClassRoom("test-room");
        //ClassRoom classRoom = new ClassRoom("save-room");
        ClassRoom classRoom = new ClassRoom("unique-room");
        classRoomRepository.save(classRoom);

        //TestStudent student = new TestStudent("test-student");
        //TestStudent student = new TestStudent("save-student");
        TestStudent student = new TestStudent("unique-student");

        student.setClassRoom(classRoom);
        studentRepository.save(student);
    }

    /** 지정한 1건에 대한 조회 Test */
    @Test
    void findStudent () {
        Optional<TestStudent> maybeStudent = studentRepository.findById((long) 1);
        TestStudent student = maybeStudent.get();

        System.out.println(student);
    }

    /** 모든 항목 조회 Test*/
    @Test
    void findAllStudents () {
        List<TestStudent> studentList = studentRepository.findAll();
        System.out.println(studentList);
    }

    /** 지정한 RoomName 으로 조회 Test */
    @Test
    void findStudentWithRoomName () {
        // Optional의 경우 1개로 확정되는 경우에만 사용해야함.
        Optional<TestStudent> maybeStudent = studentRepository.findTestStudentByRoomName("unique-room");
        TestStudent student = maybeStudent.get();

        System.out.println(student);
    }

    /** 지정한 RoomName 정보 List 로 조회 */
    @Test
    void findStudentListWithRoomName () {
        List<TestStudent> studentList = studentRepository.findTestStudentListByRoomName("save-room");

        System.out.println(studentList);
    }

    /** 수정 Test */
    @Test
    void modifyStudent () {
        Optional<TestStudent> maybeStudent = studentRepository.findTestStudentByRoomName("unique-room");
        TestStudent student = maybeStudent.get();

        ClassRoom classRoom = new ClassRoom("modify-room");
        classRoomRepository.save(classRoom);

        student.setClassRoom(classRoom);
        studentRepository.save(student);
    }

    /** 삭제 Test */
    @Test
    void deleteStudent () {
        Optional<TestStudent> maybeStudent = studentRepository.findTestStudentByRoomName("modify-room");
        TestStudent student = maybeStudent.get();

        student.setClassRoom(null);
        studentRepository.delete(student);
    }
}

 

 

테스트 실행

테스트를 실행할 때는 테스트 코드를 작성한 클래스에서 해당 기능에 대한 부분만 따로 실행을 눌러주면 된다.

그럼 콘솔에 위와 같이 테스트 인스턴스화 중.. 이란 문구가 뜨고

완료되면 테스트 결과에 테스트 통과로 나타난다.

 

 

 

DB 확인

완벽하게 잘 되었는지 확인하려면 DB를 보면 되는데,

MySQL command Line Client에서 테이블을 확인하면 된다.

 

1.  테이블 생성 잘 되었고!

테스트 실행 전
테스트 실행 후

 

2. 테이블 안에 데이터도 잘 들어가있는지 확인하면 완료! 

 

 

 

 

🔥🔥🔥

백로그 코드 작성 시 이러한 테스트는 필.수!!!

다만 너무 맹신하게 되는 것만 주의하면 된다고 한다.