Я пишу модульные тесты для репозитория, который выполняет вызовы с использованием Retrofit2.
Я хотел проверить логику после получения Call
с сервера.
Проблема: при запуске каждого теста в отдельности все они проходят, но при запуске всех тестов для класса только один проходит. Другие тесты не пройдены из-за: Wanted but not invoked: ... However, there was exactly 1 interaction with this mock:
, что относится к listener.onDataFailure()
. Причина этого: Call всегда возвращает один и тот же объект Calls.failure(IOException())
в качестве результата для каждого теста.
Код класса репозитория:
public class Repository {
private static Repository repository;
private Repository(@NonNull final RetrofitService service) {
this.service = service;
}
public synchronized static Repository getInstance(RetrofitService service) {
if (repository == null) {
repository = new Repository(service);
}
return repository;
}
public void getDataFromApi(@NonNull final DataListener listener) {
service.getData("application/json").clone().enqueue(new Callback<DataList>() {
@Override
public void onResponse(@NonNull Call<DataList> call, @NonNull Response<DataList> response) {
if (response.errorBody() == null && response.body() != null) {
listener.onDataSuccess(response.body())
} else {
listener.onDataFailure(new Exception(t.getMessage()));
}
}
@Override
public void onFailure(@NonNull Call<DataList> call, @NonNull Throwable t) {
listener.onDataFailure(new Exception(t.getMessage()));
}
});
}
}
Код класса репозиторияTest:
import com.google.common.truth.Truth.assertThat
import okhttp3.ResponseBody
import org.junit.*
import org.mockito.*
import org.mockito.Mockito.*
import retrofit2.Call
import retrofit2.Response
import retrofit2.mock.Calls
import java.io.IOException
import org.mockito.Mockito.`when` as mockitoWhen
class RepositoryTest {
@Mock
lateinit var retrofitService: RetrofitService
@Mock
lateinit var dataListener: DataListener
@Mock
lateinit var body: ResponseBody
private lateinit var repo: Repository
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
repo = Repository.getInstance(retrofitService)
}
@Test
fun `geteData given_failure result_onDataFailure called`() {
val call: Call<DataList> = Calls.failure(IOException())
mockitoWhen(retrofitService.getData(any(), any()))
.thenReturn(call.clone())
repo.getDataFromApi(dataListener)
verify(dataListener).onDataFailure(ArgumentMatchers.any())
}
@Test
fun `geteData given_success result_onDataSuccess called`() {
val call: Call<DataList> = Calls.response(Response.success(dataList))
mockitoWhen(retrofitService.getData(any(), any()))
.thenReturn(call.clone())
repo.getDataFromApi(dataListener)
verify(dataListener).onDataFailure(ArgumentMatchers.any())
}
}
Таким образом, в этом случае выше 1 тест проходит, другой не пройден в обоих случаях dataListener.onDataFailure
был вызван для одного и того же объекта.
В то время как запуск обоих методов по отдельности дает 2 прохода.
Вопрос: Почему каждый модульный тест возвращает один и тот же Call
объект (в результате которого тесты не пройдены)?