Mockito和回调“Argument(s)是不同的!”

时间:2016-02-16 19:32:22

标签: android junit mockito junit4

我正在尝试在android上使用mockito。我想用一些回调来使用它。 在这里我的测试:

public class LoginPresenterTest {


private User mUser = new User();

@Mock
private UsersRepository mUsersRepository;

@Mock
private LoginContract.View mLoginView;

/**
 * {@link ArgumentCaptor} is a powerful Mockito API to capture argument values and use them to
 * perform further actions or assertions on them.
 */
@Captor
private ArgumentCaptor<LoginUserCallback> mLoadLoginUserCallbackCaptor;

private LoginPresenter mLoginPresenter;

@Before
public void setupNotesPresenter() {
    // Mockito has a very convenient way to inject mocks by using the @Mock annotation. To
    // inject the mocks in the test the initMocks method needs to be called.
    MockitoAnnotations.initMocks(this);

    // Get a reference to the class under test
    mLoginPresenter = new LoginPresenter(mUsersRepository, mLoginView);

    // fixtures
    mUser.setFirstName("Von");
    mUser.setLastName("Miller");
    mUser.setUsername("von.miller@broncos.us");
    mUser.setPassword("Broncos50superBowlWinners");
}

@Test
public void onLoginFail_ShowFail() {

    // When try to login
    mLoginPresenter.login("von.miller@broncos.us", "notGoodPassword");


    // Callback is captured and invoked with stubbed user
    verify(mUsersRepository).login(eq(new User()), mLoadLoginUserCallbackCaptor.capture());
    mLoadLoginUserCallbackCaptor.getValue().onLoginComplete(eq(mUser));

    // The login progress is show
    verify(mLoginView).showLoginFailed(anyString());
}

但我收到了这个错误:

Argument(s) are different! Wanted:
mUsersRepository.login(
    ch.example.project.Model.User@a45f686,
    <Capturing argument>
);
-> at example.ch.project.Login.LoginPresenterTest.onLoginFail_ShowFail(LoginPresenterTest.java:94)
Actual invocation has different arguments:
mUsersRepository.login(
    ch.example.project.Model.User@773bdcae,
    ch.example.project.Login.LoginPresenter$1@1844b009
);

也许问题是第二个实际参数是ch.example.project.Login.LoginPresenter $ 1 @ 1844b009?

我跟着:https://codelabs.developers.google.com/codelabs/android-testing/#5

感谢您的帮助=)

修改

我尝试测试的方法(LoginPresenter):

@Override
public void login(String email, String password) {

    mLoginView.showLoginInProgress();

    User user = new User();
    user.setUsername(email);
    user.setPassword(password);

    mUsersRepository.login(user, new UsersRepository.LoginUserCallback() {

        @Override
        public void onLoginComplete(User loggedUser) {
            mLoginView.showLoginComplete();
        }

        @Override
        public void onErrorAtAttempt(String message) {
            mLoginView.showLoginFailed(message);
        }
    });

}

2 个答案:

答案 0 :(得分:5)

eq(new User())

使用eq(或根本不使用匹配器)时,Mockito会使用传入的实例的equals方法比较参数。除非您已定义灵活的equals对于User对象的实现,这很可能会失败。

考虑使用isA(User.class),它只会验证对象instanceof User,或any()anyObject()是否完全跳过匹配第一个参数。

答案 1 :(得分:0)

我正在使用带有rxjava 2和dagger 2的mvp模式,并且使用Mockito进行单元测试演示者。给我&#34; Argument(s)的代码是不同的!“错误:

@Mock
ImageService imageService;

@Mock
MetadataResponse metadataResponse;

private String imageId = "123456789";

@Test
public void getImageMetadata() {
    when(imageService.getImageMetadata(imageId)).thenReturn(Observable.just(Response.success(metadataResponse)));

    presenter.getImageMetaData(imageId);
    verify(view).showImageData(new ImageData()));
}

抛出错误消息,如下所示:

  

争论是不同的!通缉:实际调用有所不同   参数:com.example.model.ImageData@5q3v861

感谢@Jeff Bowman的回答,在我改变了这一行之后,它起了作用

verify(view).showImageData(new ImageData()));

verify(view).showImageData(isA(ImageData.class));