0

I write unit tests for my use cases. Many of them make network requests by calling methods of the interface, which returns them the Call object of the Retrofit library (it delegates the execution of the request to a higher level, since the use cases are at the level where network resources are not available):

// interface
interface LWRepo {

    fun getLW(
        url: String,
        limit: Long,
        offset: Long,
        headers: Map<String, String>
    ): Call<LWResponse>
}

// use case
const val LIMIT_LW: Long = 20

class GetLWDataUseCase(
    private val lWRepo: LWRepo,
    private val apiService: ApiService,
    backgroundScheduler: Scheduler,
    postExecutionScheduler: Scheduler
) : UseCase<Int, Response<LWResponse>>(
    backgroundScheduler,
    postExecutionScheduler
) {

    override fun buildUseCaseObservable(param: Int): Observable<Response<LWResponse>> {
        val response = lWRepo.getLW(
            apiService.getUrl(),
            LIMIT_LW,
            param * LIMIT_LW,
            apiService.getHeader()
        ).execute()

        return Observable.just(response)
    }
}

when i try start test for this use case:

describe("get lw data") {

        lateinit var result: Response<LWResponse>

        beforeEachTest {
            given(apiService.getUrl())
                .willReturn(apiUrl) // "${Random.nextInt()}"
            given(apiService.getHeader())
                .willReturn(header) // mock<Map<String, String>>()
            given(lWRepo.getLW(apiUrl, LIMIT_LW, param * LIMIT_LW, header))
                .willReturn(call) // mock<Call<LWResponse>>()
            given(call.execute())
                .willReturn(expectedResult) // expectedResult = Response.success(mock<LWResponse>())

            useCase.buildUseCaseObservable(param).doOnNext { result = it }.subscribe() // param = Random.nextInt(1, 10)
        }

        it("should get api url") {
            verify(apiService).getUrl()
        }

        it("should get api header") {
            verify(apiService).getHeader()
        }

        it("should do network query") {
            verify(lWRepo).getLW(apiUrl, LIMIT_LW, param * LIMIT_LW, header)
        }

        it("should get response from query") {
            verify(call).execute()
        }

        it("should return response") {
            assertEquals(result, expectedResult)
        }
}

i get fail on it("should get response from query") { verify(call).execute()} - call.execute(); Wanted 1 time; But was 4 times.

Dealing with the reasons, I also found that when the test is run, when lWRepo.getLW(...) is called, the call = "Method threw 'org.mockito.exceptions.misusing.UnfinishedStubbingException' exception. Cannot evaluate retrofit2.Call$Mockito Mock$nEws UOfl.toString()" object is returned.

What could be the problem with initializing the mock call object and repeatedly calling call.execute() if I call the useCase method only once for the test. Does the last it to check the result work correctly?

Sunbey13
  • 339
  • 4
  • 12

0 Answers0