"Status" というキーの値(文字列)とそのときの時間(long)を handleStatus() の引数として渡すようになっています。
- public class Utils {
- public interface ResultListener {
- void onError();
- void handleStatus(String status, long time);
- }
- public static void handleJson(String json, ResultListener listener) {
- if (listener == null) {
- return;
- }
- try {
- JSONObject obj = new JSONObject(json);
- String status = obj.optString("Status");
- listener.handleStatus(status, System.currentTimeMillis());
- } catch (JSONException e) {
- listener.onError();
- e.printStackTrace();
- }
- }
- }
前回紹介したように Mockito.verify() メソッドを使います。
- /**
- * Status キーがある場合、handleJson() が呼ばれることを確認する
- */
- public void testStatusKey() {
- Utils.handleJson("{\"Status\":\"hoge1\"}", mockResultListener);
- verify(mockResultListener, only()).handleStatus(anyString(), anyLong());
- }
- verify(mockResultListener, only()).handleStatus();
そこで、「引数の文字列がどんな値であっても気にしない、メソッドが呼び出されているかどうかだけ確かめたい」という場合、anyString() や anyLong() を指定することができます。
String, long 以外にも anyInt(), anyBoolean() などが用意されています。
引数の値をチェックするために、引数に直接文字列を指定することができます。
Status キーの値は正しい値を指定することができますが、long の引数は handleStatus() 内で System.currentTimeMillis() しているため、次のテストは失敗します。
失敗するテスト
- /**
- * Status キーがある場合 handleJson() が呼ばれ、引数が Status キーの値であることを確認する
- */
- public void testStatusKey() {
- Utils.handleJson("{\"Status\":\"hoge1\"}", mockResultListener);
- verify(mockResultListener, only()).handleStatus("hoge1", System.currentTimeMillis());
- }
失敗するテスト
- /**
- * Status キーがある場合 handleJson() が呼ばれ、引数が Status キーの値であることを確認する
- */
- public void testStatusKey() {
- Utils.handleJson("{\"Status\":\"hoge1\"}", mockResultListener);
- verify(mockResultListener, only()).handleStatus("hoge1", anyLong());
- }
- /**
- * Status キーがある場合 handleJson() が呼ばれ、引数が Status キーの値であることを確認する
- */
- public void testStatusKey() {
- Utils.handleJson("{\"Status\":\"hoge1\"}", mockResultListener);
- verify(mockResultListener, only()).handleStatus(eq("hoge1"), anyLong());
- }
Status キーの値は optString() で取得しているため、Status キーが無い場合は空文字になります。
失敗するテスト
- /**
- * Status キーが無い場合、handleJson() が呼ばれ引数が空文字であることを確認する
- */
- public void testNoStatusKey() {
- Utils.handleJson("{\"State\":\"hoge1\"}", mockResultListener);
- verify(mockResultListener, only()).handleStatus(eq(""), anyLong());
- }
引数をログに出力したいということがあるでしょう。そのためには verify 時に引数をキャッチしておく必要があります。
これを行ってくれるのが ArgumentCaptor です。
ここでは String と long の引数をキャッチしたいので
- ArgumentCaptor<String> statusCaptor = ArgumentCaptor.forClass(String.class);
- ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class);
あとはこの ArgumentCaptor の capture() を引数として渡します。
- /**
- * Status キーがある場合 handleJson() が呼ばれ、引数が Status キーの値であることを確認する
- */
- public void testStatusKey() {
- Utils.handleJson("{\"Status\":\"hoge1\"}", mockResultListener);
- ArgumentCaptor<String> statusCaptor = ArgumentCaptor
- .forClass(String.class);
- ArgumentCaptor<Long> timeCaptor = ArgumentCaptor.forClass(Long.class);
- verify(mockResultListener, only()).handleStatus(statusCaptor.capture(),
- timeCaptor.capture());
- String status = statusCaptor.getValue();
- long time = timeCaptor.getValue();
- assertEquals("hoge1", status);
- System.out.println("Status = " + status + ", time = " + time);
- }
ArgumentCaptor.capture() と any〇〇() は並記することができます
- verify(mockResultListener, only()).handleStatus(anyString(),
- timeCaptor.capture());
失敗するテスト
- verify(mockResultListener, only()).handleStatus("hoge1",
- timeCaptor.capture());
- verify(mockResultListener, only()).handleStatus(eq("hoge1"),
- timeCaptor.capture());
おはようございます。
返信削除mockit、とても便利ですね!