I'm using Jodd http to make requests. Is there any way to create the mock so the request doesn't happen during unit tests? I've already tried to create a mock of the send()
method but without success.
@Service
class ValidateUrlService {
val TIMEOUT = 5000
fun validateUrl(url: String): RequestVO {
var response = HttpResponse()
var timeBefore = Date()
return try{
response = HttpRequest
.post(url)
.timeout(TIMEOUT)
.connectionTimeout(TIMEOUT)
.send()
val httpStatus = response.statusCode()
buildResponseDTO(httpStatusToBoolean(httpStatus), httpStatus)
} catch (ex: Exception) {
genericExceptionHandler(ex, response.statusCode(), timeBefore)
}
}
My test
internal class ValidateUrlServiceTest{
private val service = ValidateUrlService()
@Mock
var request: HttpRequest = HttpRequest.post(ArgumentMatchers.anyString())
@Test
fun test(){
Mockito.`when`(request.send()).thenReturn(HttpResponse().statusCode(555))
service.validateUrl("https://www.example.com")
}
}
Error:
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(any());
verify(mock).someMethod(contains("foo"))
CodePudding user response:
Mocking only works with the injected objects. mocking doesn't work for those objects created inside the method scope
You can abstract out the HTTP calls to a different class
class HttpService {
fun post(url: String, timeOut: Long): HttpResponse {
return HttpRequest
.post(url)
.timeout(timeOut)
.connectionTimeout(timeOut)
.send()
}
}
class ValidateUrlService {
val httpService: HttpService
val TIMEOUT = 5000
fun validateUrl(url: String): RequestVO {
var response = HttpResponse()
var timeBefore = Date()
return try{
response = httpService.post(url, TIMEOUT)
val httpStatus = response.statusCode()
buildResponseDTO(httpStatusToBoolean(httpStatus), httpStatus)
} catch (ex: Exception) {
genericExceptionHandler(ex, response.statusCode(), timeBefore)
}
}
Now you should be able to mock the HttpService
post
method
CodePudding user response:
Your first error is here
@Mock
var request: HttpRequest = HttpRequest.post(ArgumentMatchers.anyString())
Because you are assigning to request a non mock object
If you want to use the annotations you must write you test like this: (I'm assuming that you are using JUnit5)
@ExtendWith(MockitoExtension::class)
internal class ValidateUrlServiceTest{
private val service = ValidateUrlService()
@Mock
lateinit var request: HttpRequest
@Test
fun test(){
Mockito.`when`(request.send()).thenReturn(HttpResponse().statusCode(555))
service.validateUrl("https://www.example.com")
}
}
The second one is that you are trying to mock an object that is created inside the method you are testing
You must provide an instance of HttpRequest through dependency injection (maybe using a provider injected as a constructor argument to ValidateUrlService)
Small tip:
if you want to avoid the "ugly" syntax Mockito.`when`
you can use mokito kotlin library or mockk library, both of them wrap mockito in with a more fluent kotlin way to write tests