본문 바로가기
ETC

junit 테스트코드 작성 환경에서 연결 db 변경 방법

by DanteMustDie 2023. 11. 1.
728x90

오늘 tdd 방식으로 개발 진행중, 문득 assert로 테스트는 통과했으나 jpa와 실제 db간 연동후 데이터 반/출입 확인 후 눈으로 보고싶어 이것에 대해 세팅을 하고자 했다. 스프링부트 기준으로 디폴트 세팅은 h2를 바라보게 되어있다. (굳이 db를 타는 로직을 체크하는 경우)

 

결과적으로 바꾼 정보로 db connection은 성공했으나, insert나 select시 쿼리가 정상적으로 통과하지를 못했다.

이것을 해결하고 싶어 했으나 맨토링을 듣고보니 문제를 해결하고자 함으로써 tdd 테스트의 본질을 망각해버려

유의미한 데이터 반/출입을 수행하진 못했다.

 

테스트 코드 작성은 외부 환경에 영향을 받지 않고 독립된 환경에서 로직만 테스트를 수행하여야 한다.

(db입출력 테스트는 통합테스트때 해도 충분하다는 맨토링을 들었다)

 

그럼에도 불구하고 test 코드상에서 db 연결을 하고싶어 하는 사람이 있을까?

혹은 훗날의 내가 테스트코드상이라 데이터 반입/반출이 안되는 것이 아닌, 나의 코드 이해가 잘못 되었나?

재이해를 하고자 하는 과정이 하고 싶을 때를 대비해 세팅 방법정도는 적어놓기로 했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@DisplayName("알람서비스 테스트")
@ExtendWith(MockitoExtension.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // replace NONE으로 하여 시스템 default 설정을 바라보도록 한다.
@DataJpaTest
class NotificationServiceTest {
 
    @TestConfiguration
    static class TestConfig {
 
        @Bean
        @Primary
        /* TDD 테스트시 datasource 설정 */
        public DataSource dataSource() {
            // Define your local DataSource configuration
            // For example, if using HikariCP with MySQL
            HikariConfig hikariConfig = new HikariConfig();
            hikariConfig.setJdbcUrl("jdbc:mysql://{ip_port}/{use_database}");
            hikariConfig.setUsername("{ID}");
            hikariConfig.setPassword("{PW}");
            return new HikariDataSource(hikariConfig);
        }
    }
 
    @InjectMocks
    private NotificationService notiService;
 
    @Mock
    private NotificationRepository notiRepository;
 
    @Mock
    private TemplateCollection temps;
 
    private static Stream<Arguments> param(){ // controller에서 param을 받았다는 가정 하의 더미데이터 작성.
        Long id = 6666L;
        String notiType = "addBuddy";
        long senderId = 5555L;
        long receiverId = 4444L;
        String content = senderId + TemplateCollection.contentTemplate.FRIEND_ADD.getMessage();
 
        NotificationDto dto = new NotificationDto();
       // dto.setId(id);
        dto.setNotiType(notiType);
        dto.setSenderId(senderId);
        dto.setReceiverId(receiverId);
        dto.setContent(content);
 
        return Stream.of(
                Arguments.of(dto)
        );
    }
    @DisplayName("알림 등록 테스트")
    @ParameterizedTest
    @MethodSource("param")
    void testAddNotice(NotificationDto notiDto){
        /* 시스템 도입시 notiType과 content template 정의해서 별개 파일로 관리 되도록 작업 진행 */
        /* given -- 32line에서 설정 완료 */
        /* when */
        Long resultId = notiService.addNotice(notiDto);//서비스 및 repo까지 정상 탑승 되나, 정작 db insert 로그가 찍히지 않음.
        System.err.println("resultId >>>>>> " + resultId);
        /* then */
        //assertNotNull(resultId);
 
    }
 
    @DisplayName("알림 전체 조회 테스트")
    @Test
    void testGetAllNotice(){
        /* given */
 
        /* when */
        List<NotificationDto> resultList = notiService.getAllNotice();
        int size = resultList.size();
        int value = 1;
 
        /* then */
 
        assertSame(size,value);
    }
 
    @Autowired
    private ApplicationContext context;
 
    @Test /* -- 현재 테스트 코드가 바라보는 데이터소스 정보 --  */
    public void dataSourceInfo() throws SQLException {
        DataSource ds = context.getBean(DataSource.class);
        DatabaseMetaData metaData = ds.getConnection().getMetaData();
 
        System.err.println("DataSource info -> \"+ \nURL: " + metaData.getURL()
                        + ", \ndriver: " + metaData.getDriverName()
                        + ", \nusername: " + metaData.getUserName());
    }
}
cs

 

반응형