Retrofit 1を使用して、次のようにWebサービスのモックを作成し、ネットワーク遅延をシミュレートしました。
MockRestAdapter mockRestAdapter = MockRestAdapter.from(restAdapter);
return mockRestAdapter.create(MyService.class, new MyServiceMock());
ここで、MyService
はサービスインターフェース(Rx Observableとして応答を返す)であり、MyServiceMock
はこのインターフェースを実装するクラスです。
Retrofit 2.0.0-beta3には、まだ文書化されていないまったく新しいモッキングシステムがあります(参照: https://github.com/square/retrofit/pull/134 )。同様のことをしようとすると、次のようになります。
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).build();
BehaviorDelegate<AuthService> delegate = mockRetrofit.create(MyService.class);
MyServiceMock
に通話を転送するにはどうすればよいですか?
インターフェースの定義が次のようであるとします。
public interface MyService {
@GET("/name")
rx.Observable<String> name();
}
通話はMyServiceMock
を使用してBehaviorDelegate
に転送されます。 BehaviorDelegate
は、モックによって作成された応答にNetworkBehavior
を適用します。以下のモック実装はBehaviorDelegate
をコンストラクター引数として受け取り、それを使用して応答を返すことに注意してください。
public class MyServiceMock implements MyService {
private final BehaviorDelegate<MyService> delegate;
public MyServiceMock(BehaviorDelegate<MyService> delegate) {
this.delegate = delegate;
}
public Observable<String> name() {
return delegate.returningResponse("test").name();
}
}
モックサービスを使用したテストのサンプルを以下に示します。
public class MyServiceTest {
private final NetworkBehavior behavior = NetworkBehavior.create();
private final rx.observers.TestSubscriber<String> testSubscriber = TestSubscriber.create();
private MyService mockService;
@Before
public void setUp() throws Exception {
Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl("http://example.com").build();
MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit)
.networkBehavior(behavior).build();
final BehaviorDelegate<MyService> delegate = mockRetrofit.create(MyService.class);
mockService = new MyServiceMock(delegate);
}
@Test
public void testSuccessResponse() throws Exception {
givenNetworkFailurePercentIs(0);
mockService.name().subscribe(testSubscriber);
testSubscriber.assertValue("test");
testSubscriber.assertCompleted();
}
@Test
public void testFailureResponse() throws Exception {
givenNetworkFailurePercentIs(100);
mockService.name().subscribe(testSubscriber);
testSubscriber.assertNoValues();
testSubscriber.assertError(IOException.class);
}
private void givenNetworkFailurePercentIs(int failurePercent) {
behavior.setDelay(0, MILLISECONDS);
behavior.setVariancePercent(0);
behavior.setFailurePercent(failurePercent);
}
}