Как проверить фиктивное взаимодействие внутри карты rxjava / flapmap - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь проверить этот код с помощью mockito.

public class Repository {
...
    @Override
    public Observable<Data> getCurrentData() {
        return api.getData()
                .map(entityMapper::transform);
    }
}

И я хотел бы проверить взаимодействие entityMapper. Вот мой тестовый пейзаж:

@Test
@Throws(Exception::class)
fun getData() {
    //given
    whenever(api.getData).thenReturn(Observable.just(Data()))
    //when
    debitCardRepo.getCurrentData
    //then
    verify(api).getData
    //TODO verify entityMapper interaction 
}

Если я попытаюсь verify(entityMapper).transform(anyOrNull<>()), я получу Wanted but not invoked: Кто-нибудь знает, как проверить макет взаимодействия внутри карты / flapmap?

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Вы не подписались.

debitCardRepo.getCurrentData просто вернет Observable, но на самом деле ничего не сделает.

@Test
@Throws(Exception::class)
fun getData() {
    //given
    whenever(api.getData).thenReturn(Observable.just(Data()))
    //when
    debitCardRepo.getCurrentData.subscribe()
    //then
    verify(api).getData 
}

независимо, это не очень хороший тест, так как вы тестируете побочный эффект. вызывается некоторая функция преобразования / преобразования. Почему бы вам не проверить выход?

@Test
@Throws(Exception::class)
fun getData() {
    //given
    val data = Data()
    whenever(api.getData).thenReturn(Observable.just(data))
    //when
    val transformedData = debitCardRepo.getCurrentData.blockingGet()
    //then
    assertEquals(data, transformedData)
}

Это более значимый тест. Простые рефакторинг не сломают этот тест, если не изменит поведение класса.

0 голосов
/ 05 июля 2018

Кто-нибудь знает, как проверить фиктивное взаимодействие внутри карты / карты флапа?

Предполагая, что остальная часть вашего класса выглядит следующим образом:

public class Repository {

    private final EntityMapper

    public Repository(EntityMapper entityMapper) {
        this.entityMapper = entityMapper;
    }

    @Override
    public Observable<Data> getCurrentData() {
        return api.getData()
                .map(entityMapper::transform);
    }
}

Тогда задание поведения над поддельным EntityMapper будет работать, если вы дождетесь завершения Observable:

@Test
@Throws(Exception::class)
fun testGetData() {
    //given
    val data = Data()
    whenever(api.getData).thenReturn(Observable.just(data))
    //when
    repository.getCurrentData().blockingGet()
    //then
    verify(entityMapper).transform(any())
}

Обратите внимание на вызов blockingGet() - в противном случае тест можно завершить до того, как произойдет сопоставление. Вам также следует взглянуть на метод Observable#test(), чтобы увидеть лучшие варианты здесь.

Однако в этом случае, поскольку хранилище делает очень мало, кроме делегирования API и вызова EntityMapper, и это, кажется, основное взаимодействие, которое вас интересует, почему бы не протестировать EntityMapper отдельно?

Если вы напишите отдельный тест для EntityMapper, тогда вы можете использовать тест черного ящика (просто наберите transform ваших данных и посмотрите, соответствует ли преобразование вашим ожиданиям). Этот вид тестирования гораздо более стабилен и полезен, чем тестирование в «белой коробке» с verify, которое иногда может выродиться в тесты, являющиеся обратной реализацией тестируемой системы.

...