โ—๏ธ์—๋Ÿฌ ๋ฉ”์‹œ์ง€


org.mockito.exceptions.verification.opentest4j.ArgumentsAreDifferent

 

 

 

 

 

 

๐Ÿ’ป ๊ฐœ๋ฐœ ํ™˜๊ฒฝ


  • Framework : Spring Boot 3.2.3
  • DB : MySQL(๋กœ์ปฌ), H2(ํ…Œ์ŠคํŠธ)
  • Library : JPA, QueryDSL 5.0.0
  • Test : JUnit

 

 

 

 

 

๐Ÿ”Ž ์›์ธ


Spring์—์„œ Junit์œผ๋กœ Controller ๋‹จ์˜ ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๋Š”๋ฐ, verify() ๋ถ€๋ถ„์—์„œ ๊ฒ€์ฆ์—๋Ÿฌ๊ฐ€ ๋‚ฌ๋‹ค.

 

    @Nested
    @DisplayName("๊ตฌ์ธ ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •")
    public class updateHiringPostTest {
        private Long postId;
        private HiringPostReq hiringPostReq;
        private String uid;

        @BeforeEach
        void setUp() {
            postId = 1L;
            hiringPostReq = HiringPostReq.builder()
                    ...
                    .build();

            uid = "test-uid";
        }

        @Test
        @DisplayName("๊ตฌ์ธ ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ์„ฑ๊ณต")
        public void updateHiringPost_success() throws Exception {
            // given
            doNothing().when(hiringPostService).updateHiringPost(eq(postId), eq(hiringPostReq), eq(uid));

            // when, then
            mockMvc...

	// ์—ฌ๊ธฐ์„œ ์—๋Ÿฌ๋‚จ
            verify(hiringPostService, times(1)).updateHiringPost(eq(postId), eq(hiringPostReq), eq(uid));
        }
}

 

 

 

 hiringPostService.updateHiringPost ๋ฉ”์†Œ๋“œ์˜ ํ˜ธ์ถœ์„ mock์œผ๋กœ ์„ค์ •ํ–ˆ๊ณ , verify()๋กœ ์ธ์ž๋“ค์˜ ๊ฐ’์ด ๊ฐ™์€์ง€๋ฅผ ๊ฒ€์ฆํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์—ˆ๋‹ค.

 ํ•˜์ง€๋งŒ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋‹ˆ postId์™€ uid์˜ ๊ฐ’์€ ๊ฐ™์€๋ฐ, hiringpostReq ๊ฐ์ฒด์˜ ๊ฐ’๋งŒ ๋‹ฌ๋ž๋‹ค.

 

 

Expected(์˜ˆ์ƒ ๊ฐ’)

xxx.HiringPostService#0 bean.updateHiringPost(
    1L,
    xxx.HiringPostReq@3eadad14,
    "test-uid"
);

 

Actual(์‹ค์ œ ๊ฐ’)

xxx.HiringPostService#0 bean.updateHiringPost(
    1L,
    xxx.HiringPostReq@4acc27fd,
    "test-uid"
);

 

 

3eadad14์™€ 4acc27fd๋กœ ๊ฐ์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ๊ฐ’์ด ๋‹ค๋ฅด๋‹ค.

๋‹น์—ฐํžˆ mock ๊ฐ์ฒด์™€ new๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ƒ์—์„œ ๋‹ค๋ฅธ ์ฃผ์†Œ ๊ฐ’์„ ๊ฐ–๋Š”๋‹ค.

 

 

 

์›์ธ์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์“ฐ๋Š” Mockito์˜ eq() ๋ฉ”์†Œ๋“œ์— ์žˆ๋‹ค.

 

eq() ๋ฉ”์†Œ๋“œ๋Š” ๊ฐ์ฒด์˜ ๋น„๊ต๋ฅผ ์œ„ํ•ด equals() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ž๋ฐ”์—์„œ equals() ๋ฉ”์†Œ๋“œ๋Š” ๊ฐ์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ๋‘ ๊ฐ์ฒด์˜ ์ฃผ์†Œ ๊ฐ’์ด ๋‹ฌ๋ผ false๋ฅผ ๋ฐ˜ํ™˜ํ•ด ํ…Œ์ŠคํŠธ์— ์‹คํŒจํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

 ๋‘ ๊ฐ์ฒด์˜ ์ฃผ์†Œ ๊ฐ’์ด ๋‹ฌ๋ผ๋„ ๋‚ด์šฉ์ด ๊ฐ™๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

 

 

 

 

 

๐Ÿ’ก ํ•ด๊ฒฐ


๋‘ ๊ฐ์ฒด์˜ ๋น„๊ต ๊ธฐ์ค€์„ ์™„ํ™”ํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿผ ๊ฐ์ฒด์˜ ๋น„๊ต ๊ธฐ์ค€์„ ์–ด๋–ป๊ฒŒ ์™„ํ™”ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

 

 

 

 

 

๋ฐฉ๋ฒ• 1 : any() ์‚ฌ์šฉ

verify(hiringPostService, times(1)).updateHiringPost(eq(postId), any(HiringPostReq.class), eq(uid));

 

any()๋Š” ์‹ค์ œ๋กœ ๊ฐ์ฒด์˜ ๊ฐ’์„ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋œ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐ์ฒด์˜ ๊ฐ’ ๊ฒ€์ฆ์€ ์–ด๋ ต์ง€๋งŒ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ์ด ๋˜์—ˆ๋Š”์ง€๋งŒ ํ™•์ธํ•˜๋Š” ์šฉ๋„๋กœ ์“ธ ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

 

 

๋ฐฉ๋ฒ• 2 : @EqualsAndHashCode ์ถ”๊ฐ€

Lombok์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, @EqualsAndHashCode๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค. Lombok์—์„œ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ํ•„๋“œ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๋น„๊ต๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.

@Getter
@EqualsAndHashCode //์ถ”๊ฐ€
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class HiringPostReq {
	...
}

 

 

@EqualsAndHashCode๋Š” @Data์— ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ๋„ ํ•˜๋‹ค. @Data๋ฅผ ์“ฐ๊ณ  ์žˆ์—ˆ๋‹ค๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚˜์ง€ ์•Š์•˜์„ํ…๋ฐ, ๋‚˜๋Š” ๋ฌด๋ถ„๋ณ„ํ•œ ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ์œผ๋กœ ์ธํ•œ ๋ถ€์ž‘์šฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด @Data ์‚ฌ์šฉ์„ ์ง€์–‘ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋‚œ ๊ฒƒ์ด๋‹ค.

 

 ํ•˜์ง€๋งŒ, @EqualsAndHashCode ์‚ฌ์šฉ๋„ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. DTO๋Š” ๋ฌธ์ œ๊ฐ€ ์—†๊ฒ ์ง€๋งŒ, Entity์— ์“ธ ๋•Œ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

 ๋ชจ๋“  ํ•„๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ equals()์™€ hashCode()๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. JPA๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์—ฐ๊ด€ ๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ํ•„๋“œ์˜ ๊ฒฝ์šฐ ์ง€์—ฐ ๋กœ๋”ฉ์ด ๊ฐ•์ œ๋กœ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์–‘๋ฐฉํ–ฅ ๊ด€๊ณ„์ผ ๋•Œ, ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ์ ๋„ ๋ฌธ์ œ๋‹ค.

 

 

 

 

 

 ๋‚ด๊ฐ€ ๊ฒ€์ฆํ•˜๋ ค๋˜ ๋ถ€๋ถ„์€ DTO์ด๊ธฐ ๋•Œ๋ฌธ์— @EqualsAndHashCode๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†์„ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ•˜์—ฌ ๋ฐฉ๋ฒ• 2๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ Entity๋ฅผ ๊ฒ€์ฆํ•ด์•ผ ํ–ˆ๋‹ค๋ฉด any()๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

 

 

 

 

 

๐Ÿ“– ์ฐธ๊ณ 


 

giraffe_