I want to mock this webclient post call. Service
fun <T : Any> post(uri: String, body: Any, responseType: Class<T>): Class<T>? {
return webClient.post()
.uri(uri)
.bodyValue(body)
.retrieve()
.bodyToMono(responseType::class.java)
.block()
}
I am getting a null pointer exception when I am mocking bodyToMono using a Class<T> generic.
ServiceTest
@Mock
lateinit var mockWebClient: WebClient
@Autowired
private lateinit var onelinkRestClient: OnelinkRestClient
@Mock
private lateinit var requestHeadersMock: WebClient.RequestBodyUriSpec
@Mock
private lateinit var responseMock: WebClient.ResponseSpec
@Mock
private lateinit var requestBodyUriMock: WebClient.RequestBodyUriSpec
@Mock
private lateinit var requestBodyMock: WebClient.RequestBodySpec
@BeforeEach
fun setUp() {
webclient = Service(mockWebClient)
}
val uri = "/path"
`when`(mockWebClient.post()).thenReturn(requestBodyUriMock)
`when`(requestBodyUriMock.uri(uri)).thenReturn(requestBodyMock)
`when`(requestBodyMock.bodyValue((requestDTO))).thenReturn(requestHeadersMock)
`when`(requestHeadersMock.retrieve()).thenReturn(responseMock)
`when`(responseMock.bodyToMono(ResponseDTO::class.java)).thenReturn(Mono.just(responseDTO))
val response = webclient.post<ResponseDTO>("/path", responseDTO, responseDTO::class.java)
When running serviceTest, it gives me an error:
java.lang.NullPointerException: Cannot invoke "reactor.core.publisher.Mono.block()" because the return value of "org.springframework.web.reactive.function.client.WebClient$ResponseSpec.bodyToMono(java.lang.Class)" is null
If I change it from generic Class<T> to a some Class defined it doesn't throw NPE
fun <T : Any> post(uri: String, body: Any, responseType: Class<T>): Class<T>? {
return webClient.post()
.uri(uri)
.bodyValue(body)
.retrieve()
.bodyToMono(responseType::class.java)
.block()
}
Insted of bodyToMono of responseType::class.java, when I do it with defined class, the testcase passes.
eg
.bodyToMono(abc::class.java)
I am trying to mock a generic class of type T Class<T> in bodyToMono.
CodePudding user response:
I think your test is correct, but your function is wrong. It calls ::class
on a Class
instance, so you will always end up with a Class<Class<?>>
.
Don't you want the following?
.bodyToMono(responseType)
or perhaps:
.bodyToMono(responseType.java)
(I don't know Kotlin well enough)