Как проверить функцию внутри RxJava flatMap? - PullRequest
0 голосов
/ 04 июля 2019

У меня есть следующий метод в презентере.

public void addNote(int customerId, String body) {
    disposables = RxUtil.initDisposables(disposables);

    if (TextUtils.isEmpty(body)) {
        view.showNoteTextEmpty();
        return;
    }

    if (customerId == Constants.ZERO) {
        view.showNoteError("There is a problem with adding note. Try again!");
        return;
    }

    Disposable disposable = userPrefRepository.getLoggedInUser()
        .subscribeOn(Schedulers.io())
        .map(user -> getNote(body, user))
        .flatMap(note -> customersRepository.addNote(customerId, note))
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(response -> {
            if (response.isSuccessful()) {
                view.onNoteAdded();
            } else if (response.code() == 401) {
                view.handleUnauthorisedError();
            } else {
                view.onNoteNotAdded();
            }
        }, view::handleError);

    disposables.add(disposable);
}

Теперь я хочу протестировать его следующим классом:

@RunWith(PowerMockRunner.class) @PrepareForTest(TextUtils.class)
public class NoteDetailsPresenterTest extends BaseTest {

    @Rule TrampolineSchedulerRule trampolineSchedulerRule = new  TrampolineSchedulerRule();

    @Mock CustomersRepository customersRepository;
    @Mock UserRepository userRepository;
    @Mock RolesManager rolesManager;
    @Mock NoteDetailsPresenter.View view;

    private NoteDetailsPresenter presenter;

    @Before
    public void setUp() {
        mockTextUtils();
        presenter = new NoteDetailsPresenter(customersRepository, userRepository, rolesManager);
        presenter.setView(view);
    }

    @Test
    public void shouldAddNote() {
        // Given
        User user = User.newBuilder()
            .withUserId(1)
            .build();

        // When
        Mockito.when(userRepository.getLoggedInUser()).thenReturn(Single.just(user));
        Note note = presenter.getNote("Note body", user);
        Response<Note> response = Response.success(200, note);
        Mockito.when(customersRepository.addNote(1, note)).thenReturn(Single.just(response));
        presenter.addNote(1, "Note body");

        // Then
        Mockito.verify(view).onNoteAdded();
    }
}

Но происходит сбой со следующим исключением:

Разыскивается, но не вызывается: view.onNoteAdded (); -> at com.anstar.presentation.notes.NoteDetailsPresenterTest.shouldAddNote (NoteDetailsPresenterTest.java:56)

Однако были другие взаимодействия с этим макетом: view.handleError ( java.lang.NullPointerException: сингл, возвращаемый средством отображения, является нулем ); -> at io.reactivex.internal.observers.ConsumerSingleObserver.onError (ConsumerSingleObserver.java:46)

Как я могу это решить? Проблема в преобразованиях карты и flatMap?

1 Ответ

1 голос
/ 04 июля 2019

Кажется, что макет не читается. Попробуйте поставить any() по параметрам:

Вместо этого:

Mockito.when(customersRepository.addNote(1, note)).thenReturn(Single.just(response));

Использование any():

Mockito.when(customersRepository.addNote(anyInt(), any(Note.class))).thenReturn(Single.just(response));

Почему макет не может читать?

Если параметры относятся к примитивным типам данных (string, int, double и т. Д.), Вы можете просто передать точный параметр (в вашем случае первый параметр, который является целым числом, 1), и макет будет прочитан. Однако в объектах (в вашем случае, Note объект), даже если у вас одни и те же точные параметры, они будут иметь разные hashCode(), поэтому макет не может быть прочитан. Для этого нужно принять параметр any(), указывающий тип класса: any(Note.class).

...