-
Mockk(relaxed = true) 는?언어/Kotlin 2023. 3. 13. 23:00
테스트 코드를 짜다보면 특정 클래스의 메서드가 특정 방식이 반환되기를 기대할 때 종종 Mock을 이용해 테스트를 짭니다. 언어마다 여러가지 목킹 도구들이 있고, 그중 코틀린은 Mockk 가 주로 사용됩니다.
코틀린의 테스트 코드를 보면 모킹을 다룰 때 mockk(relaxed = true) 로 되어있는것을 볼 수 있습니다. relaxed = true 를 파라미터로 줄 때와 그렇지 않을 때의 사용방법이 어떻게 다른지 비교해보겠습니다.
relaxed = true
// Member.kt @Entity class Member( @Column(name = "name") val name: String, ) { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private val id: Long? = null @Column(name = "deleted_at") private val deletedAt: String? = null } // PaymentService.kt @Service class PaymentService(private val memberRepository: MemberRepository) { fun getBoolean() = true fun getInt(): Int { return 1 } fun getString() = "Hello" fun getLong() = 1L fun getFloat() = 1.0f fun getMember() = Member("fightnyy") fun saveMemberFromDB(): Member { return memberRepository.save(Member("fightnyy")) } } // MockTest.kt @SpringBootTest @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) class MockTest { val paymentService = mockk<PaymentService>(relaxed = true) @Test @DisplayName("Mock Test") fun testLong(): Any { every { memberRepository.save(any()) } returns Member("Nice") println("result of Boolean : " + paymentService.getBoolean()) // false println("result of Long! : " + paymentService.getLong()) // 0 println("result of Int : " + paymentService.getInt()) // 0 println("result of String : " + paymentService.getString()) // "" println("result of String is same as empty? : " + paymentService.getString().isEmpty()) // true println("result of Float : " + paymentService.getFloat()) // 0.0 println("result of Member : " + paymentService.getMember()) // Member(child of #2#4) println("result of Member from DB : " + paymentService.saveMemberFromDB()) // Member(child of #2#5) // 여기서 반환되는 Member의 값은 name = "", id = 0, deleted_at = "" 입니다. } }
- relaxed = true 옵션을 주게 되면 primitive 값들은 모두 기본값(0, false, "")을 반환하게 됩니다. 또한 클래스의 경우에는 chained mocks 리턴됩니다.(Member(child of #2#4) 같은 형식인데 클래스 내부 primitive 값들은 모두 기본값들을 반환합니다.)
- 만약 relaxed = true 옵션을 주지 않게 되면 어떤일이 벌어질까요?
- no answer found for: ...... 와 같은 형식의 에러 로그로 반환됩니다. 즉 목킹은 했는데 해당 목킹에 반환 값을 적용해주지 않았다는 의미입니다.
relaxUnitFun = true
- 해당 옵션은 Unit 으로 반환되는 함수들만 목킹합니다. 위의 paymentService 에 함수를 하나 추가해보겠습니다.
- 해당 함수는 relaxUnitFun = true 옵션을 줘도 되고 relaxed = true 옵션을 줘도 테스트가 통과하지만, 어떠한 파라미터도 주지 않은 경우는 다시 no answer found for: ....... 로그가 나옵니다.
- relaxUnitFun 은 반환타입이 Unit 인(즉, 함수가 아무것도 반환되지 않는 경우) 함수만 테스트에 모킹된 것처럼 동작합니다.
@Service class PaymentService( private val memberRepository: MemberRepository) ){ // ... fun unitFunction(): Unit { println("unitFunction") } }
'언어 > Kotlin' 카테고리의 다른 글
Kotlin safe call (0) 2022.11.29 Kotlin 에 대해서 알게 된 것들 (0) 2022.10.11