Test Class Template
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
@Config(sdk = LOLLIPOP, constants = BuildConfig.class)
@RunWith(RobolectricGradleTestRunner.class)
public class MyTest {
// something to mock
@Mock TypeA A;
@Spy TypeB B = new TypeB();
// ...
// Set up
@Before public void setUp() throws Exception {
initMocks(this); // create mock objects, ex. A and B above
// ... do so other init things
}
// Tear down
@After public void tearDown() {
// ... do so tear down things
}
// Test Case (which should not throw exception)
@Test public void testCase1() throws Exception {
// do something
}
// Test Case (expect exception)
@Test(expected=YouExceptException.class) public void testException1() {
// something would throw YouExceptException.class exception
}
// Test Case (expect exception)
@Test public void testException2() throws Exception {
try {
// something should throw exception
// import org.assertj.core.api.Assertions;
Assertions.failBecauseExceptionWasNotThrown(YouExpectException.class);
} catch (YouExpectException e) {
}
// verify other things here
}
// Test Case (with timeout)
@Test(timeout=100) public void infinity() {
// something should not run longer than 100ms
}
}
====
Mock something (create a fake object)
1. Use @Mock to create mock member variables. (see above)
2.
MyClass mockObject = Mockito.mock(MyClass.class);
3. Mock Generic Type Class
MyClass<T> mockObject = (MyClass<T>) Mockito.mock(MyClass.class);====
When ( tell the mock objects what to return )
// tell the object what to return when its function is called.
when(mockObject.functionA()).thenReturn(valueA);
when(mockObject.functionB()).thenReturn(valueB);
// return different values based on the input
when(mockObject.functionC(inputA)).thenReturn(valueA);
when(mockObject.functionC(inputB)).thenReturn(valueB);
// return a value based on the type of the provide parameter
// use anyInt(), anyString()...
when(mockObject.functionD(anyInt())).thenReturn(-1);
when(mockObject.functionD(isA(ThisIsAClass.class))).thenReturn(0);
// return different values if the function may be called many times
// Iterator i= mock(Iterator.class);
when(i.next()).thenReturn("first").thenReturn("second");
====Spy something (create a real object, but fake some of its functions)
MyClass spyObject = spy(new MyClass());
//You have to use doReturn() for stubbing
doReturn("foo").when(spyObject).functionA();
====Verify
// verify functionA is called once
verify(mockObject).functionA();
// verify functionB with parameter valueA is called once
verify(mockObject).functionB(Matchers.eq(valueB));
// verify function is called many times
verify(mockObject, times(2)).functionA();
// verify function is never called
verify(mockObject, never()).functionC();
verify(mockObject, never()).functionD(anyInt());
// other verify functions
verifyZeroInteractions(mockObject);
verify(mock, atLeastOnce()).someMethod("called at least once");
verify(mock, atLeast(2)).someMethod("called at least twice");
verify(mock, atMost(3)).someMethod("called at most 3 times");
// if one of the parameter use the matcher, all parameters have to use matcher.
// this is correct
verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
// the following will throw exception
// verify(mock).someMethod(anyInt(), anyString(), "third argument");
====assertThat (check value)
(org.assertj.core.api.Assertions.assertThat)
assertThat(obj.functionA()).isFalse();
assertThat(obj.functionA()).isTrue();
assertThat(obj.functionA()).isNull();
assertThat(obj.functionA()).isNotNull();
assertThat(obj.functionA()).isEqualTo("ABC");
assertThat(obj.functionA()).isNotEqualTo("ABC");
====Observable Testing (Using TestSubscriber)
Subscriber====subscriber = spy(new TestSubscriber ()); // ... Observable observable = CreateAnObservable(); // new an Observable observable.subscribe(subscriber); // Something you can verify subscribe.assertNoErrors(); verify(subscriber, times(2)).onNext(cursor); verify(subscriber).onNext(cursor); verify(subscriber, never()).onError(any(Throwable.class)); verify(subscriber).onCompleted();
1. any(String.class) 和 anyString()
any(String.class) 包含 null和任何String
anyString() 只包含任何String, 不包含Null
2. new出來的obj (不是mock出來的obj) 才有method的實作
如果要改變obj中其中的幾個method的回傳值
要先用spy()來得到spy obj
然後用doReturn(returnValue).when(...)
3. mock出來的obj 沒有method的實作
要用when(...).thenReturn(...) 來控制obj內的method會回傳什麼
4. static和final的method, class...等無法mock
如果想要測試static function
只能把static function多包一層放在某個class的non-static function內