Mockito

虛擬物件

用來驗證是否如預期的互動行為,例如:

void add(List<String> list, String item) {
   list.add(item);
}

void testAddList() {
    List<String> mockedList = mock(List.class);
    add(mockedList, "one");
    verify(mockedList).add("one");
}

也可以偽裝行為,例如:

LinkedList mockedList = mock(LinkedList.class);

// 如果有人呼叫 get(0) ,就回傳 "first"
when(mockedList.get(0)).thenReturn("first");

assertEquals("first", mockedList.get(0));

RxParse 測項範例

測試 ParseObservable.all(ParseQuery).subscribe(onNext, onError, onCompleted); ,不應該先呼叫 onCompleted 才呼叫 onNext。

  /**
   * <code>ParseObservable.all(ParseQuery).subscribe(onNext, onError, onCompleted);</code> should've onNext after onCompleted.
   */
  @Test
  public void testParseObservableAllNextAfterCompleted() {
    // 建立三個偽裝 ParseUser
    ParseUser user = mock(ParseUser.class);
    ParseUser user2 = mock(ParseUser.class);
    ParseUser user3 = mock(ParseUser.class);
    List<ParseUser> users = new ArrayList<>();
    when(user.getObjectId()).thenReturn("" + user.hashCode()); // 偽裝呼叫 user.getObjectId() 時,回傳 hashCode 字串.
    users.add(user);
    when(user2.getObjectId()).thenReturn("" + user2.hashCode());
    users.add(user2);
    when(user3.getObjectId()).thenReturn("" + user3.hashCode());
    users.add(user3);
    // 偽裝 ParseQueryController ,讓 ParseQuery.findInBackground(), ParseQuery.countInBackground 使用到偽裝的 ParseQueryController
    ParseQueryController queryController = mock(ParseQueryController.class);
    ParseCorePlugins.getInstance().registerQueryController(queryController);

    Task<List<ParseUser>> task = Task.forResult(users);
    // 偽裝呼叫 findAsync(ParseQuery.State, ParseUser, Task) 時,回傳已經裝好三個使用者的 task
    when(queryController.findAsync(
            any(ParseQuery.State.class),
            any(ParseUser.class),
            any(Task.class))
    ).thenReturn(task);

    // 偽裝呼叫 countAsync(ParseQuery.State, ParseUser, Task) 時,回傳使用者個數: 3
    when(queryController.countAsync(
      any(ParseQuery.State.class),
      any(ParseUser.class),
      any(Task.class))).thenReturn(Task.<Integer>forResult(users.size()));

    ParseQuery<ParseUser> query = ParseQuery.getQuery(ParseUser.class);
    query.setUser(new ParseUser());

    final AtomicBoolean completed = new AtomicBoolean(false);
    rx.parse.ParseObservable.all(query)
        //.observeOn(Schedulers.newThread())
        //.subscribeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<ParseObject>() {
        @Override public void call(ParseObject it) {
            System.out.println("onNext: " + it.getObjectId());
            if (completed.get()) { // 竟然發現 onCompleted 已經被呼叫了
                fail("Should've onNext after onCompleted.");
            }
        }
    }, new Action1<Throwable>() {
        @Override public void call(Throwable e) {
            System.out.println("onError: " + e);
        }
    }, new Action0() {
        @Override public void call() {
            System.out.println("onCompleted");
            completed.set(true);
        }
    });

    try {
        ParseTaskUtils.wait(task); // 因為是非同步執行,需要等待 task 把結果送出,確保 callbacks 跑完。
    } catch (Exception e) {
        // do nothing
    }
  }

安裝

dependencies { testCompile "org.mockito:mockito-core:1.+" }

See Also

results matching ""

    No results matching ""