Open emiling opened 2 years ago
같은 코드를 JAVA로 작성하면 문제가 없는데 Kotlin 코드 상에서 문제가 되는 것이 이상해서 테스트 코드 부분을 Kotlin Decompile 했더니 다음과 같았다.
ArgumentCaptor var5 = ArgumentCaptor.forClass(Bucket.class);
Intrinsics.checkNotNullExpressionValue(var5, "ArgumentCaptor.forClass(…Bucket::class.java)");
ArgumentCaptor captor = var5;
BucketService var6 = this.service;
if (var6 == null) {
Intrinsics.throwUninitializedPropertyAccessException("executor");
}
var6 = (BucketService)Mockito.verify(var6, Mockito.times(1));
Object var10001 = captor.capture();
Intrinsics.checkNotNullExpressionValue(var10001, "captor.capture()"); // 여기서 NPE발생
var6.execute((Bucket)var10001);
execute
함수의 파라미터는 Bucket?
이 아니라 Bucket
이므로 null을 허용하지 않고 있다execute
함수를 실행하기 이전에 Intrinsics.checkNotNullExpressionValue
로 captor.capture
값을 체크한다captor.capture
는 mockito에서 선언된 타입이라 Platform Type 으로 Kotlin 컴파일러로 간주되어 nullable
로 처리된다execute
가 실행되기 전까지는 captor.capture
값이 null인 것이 당연하므로 null check 를 하지 않아야 하는데 수행하고 있다ArugmentCaptor
의 타입을 non-nullable
로 "명시적으로" 선언한다ArgumentCaptor<Bucket!>!
이런 식으로 전환된다
val captor = ArgumentCaptor<Bucket> = ArgumentCaptor.forClass(Bucket::class.java)
@Suppress("UNCHECKED_CAST")
private fun <T> capture(captor: ArgumentCaptor<T>): T = captor.capture()
T
가 non-nullable 이면 해당 리턴값도 non-nullable이 된다.private final Object capture(ArgumentCaptor captor) {
return captor.capture();
}
...
((BucketService)Mockito.verify(var6, Mockito.times(1))).execute((Bucket)this.capture(captor));
...
참고 : Mockito - Kotlin test throws Null Pointer Exception when trying to capture Pageable argument
Kotlin에서 Mockito 사용하여 테스트 할 때 유의할 점
ArgumentCaptor<T>
를 사용하여 테스트 코드를 작성했는데