问题
我正在尝试使用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();
}
});
}
}
答案 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依赖项以供它使用。