レトロフィットAPI呼び出しメソッドをアクティビティコードから分離し、これらのメソッドで単体テストを実行したいと思います。1つの例:インターフェイス:
public interface LoginService {
@GET("/auth")
public void basicLogin(Callback<AuthObject> response);
}
これは呼び出しを行うメソッドです。メインアクティビティでは、イベントバスによってオブジェクトを取得します。
public class AuthAPI {
private Bus bus;
LoginService loginService;
public AuthAPI(String username, String password) {
this.bus = BusProvider.getInstance().getBus();
loginService = ServiceGenerator.createService(LoginService.class,
CommonUtils.BASE_URL,
username,
password);
}
public void Login() {
loginService.basicLogin(new Callback<AuthObject>() {
@Override
public void success(AuthObject authObject, Response response) {
bus.post(authObject);
}
@Override
public void failure(RetrofitError error) {
AuthObject authObject = new AuthObject();
authObject.setError(true);
bus.post(authObject);
}
});
}
}
そしてここでテスト
@RunWith(MockitoJUnitRunner.class)
public class AuthCallTest extends TestCase {
AuthAPI authAPI;
@Mock
private LoginService mockApi;
@Captor
private ArgumentCaptor<Callback<AuthObject>> cb;
@Before
public void setUp() throws Exception {
authAPI = new AuthAPI("username", "password");
MockitoAnnotations.initMocks(this);
}
@Test
public void testLogin() throws Exception {
Mockito.verify(mockApi).basicLogin((cb.capture()));
AuthObject authObject = new AuthObject();
cb.getValue().success(authObject, null);
assertEquals(authObject.isError(), false);
}
}
テストを開始すると、このエラーが発生します
Wanted but not invoked:
mockApi.basicLogin(<Capturing argument>);
-> at AuthCallTest.testLogin(AuthCallTest.Java:42)
Actually, there were zero interactions with this mock.
私が間違ったこと、これは私を夢中にさせています私は成功せずにこのガイドに従おうとしました: http://www.mdswanson.com/blog/2013/12/16/reliable-Android-http-testing-with -retrofit-and-mockito.html
誰か助けて :(
セットアップ手順を見逃しているため、記事はあまり明確ではありません。記事にリンクされている GitHubプロジェクト にアクセスすると、不足している手順を説明する完全なソースコードを確認できます。
1)コードサンプルは、特定のアクティビティをテストするテストクラスから抽出されます。セットアップの一部として(つまり、_@Before
_で)、GitHubAPI実装へのアクティビティの参照をモックのものに置き換えます。次に、アクティビティのonCreate()
を呼び出します。
2)onCreate()
の間に、アクティビティは現在置き換えられているGitHub APIを呼び出し、そのCallback
オブジェクトを渡します。
これらの最初の2つのステップは、各テストの開始時にMockito.verify(mockApi).repositories(Mockito.anyString(), cb.capture());
ステップが機能する理由を説明しています。テストは_@Before
_の後に実行されるため、mockApiは実際にそのrepositories()
メソッドを呼び出しています。
コードの残りの部分は、それが配置されると理解しやすくなります。彼はmockApi
を作成しただけで、実際に使用されているCallback
は変更していないため、アクティビティのコンテンツが変更されます。次に、コードの残りの部分は、ListViewまたはToastsをチェックすることにより、これらの変更が行われたことを確認します。
したがって、あなたの質問に答えるには、次のことを行う必要があります。
1)テストメソッドの開始時に、AuthAPIのloginServiceオブジェクトをmockApiオブジェクトに置き換えてから、AuthAPI.Login()
を呼び出します。
2)関数が呼び出されたことを確認するために、verify()
を使用します。
3)サンプルAuthObject
を作成し、それをcb.getValue().success()
関数に渡します。
4)AuthObject
からBus
を取得し、それがcallback.success()
関数に送信したものと同じであることを表明します。
これは、AuthAPI.Login()
がRetrofitから取得するBus
をAuthObject
に正しく送信することをテストします。
(SOの質問は少し前に書かれたものですが、最近同じ記事に出くわして同じ混乱があったので、この答えを思いました他の人にも役立つかもしれません。)
問題は、間違ったタイミングでverify
を呼び出すことです。verify
の目的は、mockApiとの相互作用が期待どおりであることを確認することです。したがって、通常は次のように表示されます。
authApi.login();
Mockito.verify(mockApi).basicLogin((cb.capture()));
これは、エラーメッセージが示していることでもあります。verify
はbasicLogin
が呼び出されることを期待していましたが、そうではありませんでした。
私もその記事を読んで、何か足りないものがあると感じました。私は実際にはまだ引数のキャプチャを理解していません。だからそれであなたを助けることはできません:)