Mockito MockApi返回null

时间:2016-04-15 10:08:41

标签: android mockito retrofit rx-java

问题

我正在尝试使用Mockapi测试我的logIn()方法。不幸的是,每当我在subscribe上尝试Observer时,我都会null object reference,因为logIn()会返回null

我不明白问题出在哪里。为什么我的模拟api不会返回数据?

CODE

### logInTest ###

@RunWith(MockitoJUnitRunner.class) 
@LargeTest
public class LogInTest {

@Mock
MockAPI mockAPI;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void performValidLogIn() throws Exception {
    LoginResponse expectedResponse = new LoginResponse();
    expectedResponse.setToken("RANDOM TOKEN");

    TestSubscriber<LoginResponse> testSubscriber = new TestSubscriber<>();
    Observable<LoginResponse> observable = mockAPI.logIn(new LogInData("TestLogin", "TestPassword"));
    observable.subscribe(testSubscriber);
    testSubscriber.assertNoErrors();
    testSubscriber.assertReceivedOnNext(Collections.singletonList(expectedResponse));
}
}

### MockAPI ###

public class MockAPI implements API {

@Override
public Observable<LoginResponse> logIn(@Body LogInData logInData) {
    return Observable.create(new Observable.OnSubscribe<LoginResponse>      () {
        @Override
        public void call(Subscriber<? super LoginResponse> subscriber) {
            LoginResponse testData = new LoginResponse();
            testData.setToken("RANDOM TOKEN");
            subscriber.onNext(testData);
            subscriber.onCompleted();
        }
    });
}
}

2 个答案:

答案 0 :(得分:1)

该对象被模拟,但不知道如何对您的方法调用进行操作,您需要通过调用f.e

来指定它。
when(mockAPI.logIn(any(LogInData.class))).thenReturn(Observable.just(new LoginResponse());

答案 1 :(得分:1)

Mockito为您提供了一个可模拟对象的目标类/接口,因此不需要MockAPI类。在初始化期间,Mockito还会在目标类周围创建一个基本上空白的shell - 稍后您将使用when方法逐步定义行为。

在您的方案中,通过使用@Mock注释MockAPI,Mockito正在模拟您的 MockAPI 而不是您的API。 login方法返回null,因为尚未通过Mockito定义任何行为。

更改字段以直接模拟您的API:

@Mock
API mockApi;

然后,您将在测试体中定义logIn方法以返回所需的Observable:

@Test
public void performValidLogIn() throws Exception {
    LoginResponse expectedResponse = new LoginResponse();
    expectedResponse.setToken("RANDOM TOKEN");
    when(mockApi.logIn(any(LogInData.class))).thenReturn(Observable.just(expectedResponse));

    TestSubscriber<LoginResponse> testSubscriber = new TestSubscriber<>();
    Observable<LoginResponse> observable = mockAPI.logIn(new LogInData("TestLogin", "TestPassword"));
    observable.subscribe(testSubscriber);
    testSubscriber.assertNoErrors();
    testSubscriber.assertReceivedOnNext(Collections.singletonList(expectedResponse));
}

附注:来自您提供的测试用例(假设它没有被设计),我想要测试您的登录方法的行为。但是,通过模拟该方法本身,您实际上将测试 mock 而不是生产代码。理想情况下,您需要测试一个真正的类来运行您的API的登录方法,然后传入模拟的API依赖项以供它使用。