Android????????????
?????kachidokima ???????[ 2017/6/12 10:19:12 ] ??????????????? ???????
???????????????????????????JUit+Mock+Espresso?????????????????????????????????????????????ɡ?
?????????????????????????????????????????????????д???Щ??????????????????????
????JUnit
????????
//??????Java?????2??????????????????????????
????testCompile 'junit:junit:4.12'
????//??????????Android?????????????
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support:support-annotations:'+supportLibVersion
//??defaultConfig??????????
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
???????
????????Java??????????????????????????????????????
public int add(int one?? int another) {
return one + another;
}
????????д???????????????
public int test() {
Calculator calculator = new Calculator();
int sum = calculator.add(1?? 2);
if(sum == 3) {
System.out.println("add() works!")
} else {
System.out.println("add() does not works!")
}
}
???????????????????????
//??????????????????
@Before
public void setup() {
mCalculator = new Calculator();
}
@Test
public void testAdd() throws Exception {
int sum = calculator.add(1?? 2);
Assert.assertEquals(3?? sum);
}
//????????????
@Test(expected = IllegalArgumentException.class)
public void test() {
mCalculator.divide(4?? 0);
}
???????????????Assert???У?????????????????о???
??????????3???????
????setUp/@Before??????????????????????????
????tearDown/@After???????????????????к????
????setUpBeforeClass/@BeforeClass?????????????????????????
????tearDownAfterClass/@AfterClass???????????????????????????
????Junit3??????????????????test?????Junit4????????????????????????@Test????
?????????????????????????????????????@Ignore
???????
????Parameterized
?????????????????????????????5??
?????? @RunWith(Parameterized.class) ????? test ??
????????????? @Parameters ??????????????????????????????????(????)????????????????
?????????????????????????????????в????????????????
????????в????????????????????
????????????????????????????????????????????
?????
@RunWith(Parameterized.class)
public class CalculatorAddParameterizedTest {
@Parameters
public static Iterable<Object[]> data() {
return Arrays.asList(new Object[][]{
{0?? 0?? 0}??
{0?? -1?? -1}??
{2?? 2?? 4}??
{8?? 8?? 16}??
{16?? 16?? 32}??
{32?? 0?? 32}??
{64?? 64?? 128}});
}
private final double mOperandOne;
private final double mOperandTwo;
private final double mExpectedResult;
private Calculator mCalculator;
public CalculatorAddParameterizedTest(double operandOne?? double operandTwo??
double expectedResult) {
mOperandOne = operandOne;
mOperandTwo = operandTwo;
mExpectedResult = expectedResult;
}
@Before
public void setUp() {
mCalculator = new Calculator();
}
@Test
public void testAdd_TwoNumbers() {
double resultAdd = mCalculator.add(mOperandOne?? mOperandTwo);
assertThat(resultAdd?? is(equalTo(mExpectedResult)));
}
}
????Rule
??????????@Before??@After?????????????????????????????????????????Щ???????????????????????е?Rule??????
?????????????????
????Junit Rule?????
????Mockito
????????
androidTestCompile "org.mockito:mockito-core:$mockitoVersion"
????Mock????
?????????????????????????????????????????????Mock????????????????????????
????Mock??????????????????????????????????hook??????????????????Stub????????????????
????Spy???????????????????????????????????????????hook????
???????
????????Mock
???????Rule
@Mock
MyDatabase databaseMock;
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
???????RunWith
@RunWith(MockitoJUnitRunner.class)
public class Test{
@Mock
MyDatabase databaseMock;
}
???????mock
MyClass test = mock(MyClass.class);
???????Stub
????????????????????????????????
??????е??????????????matcher???????е?????????????matcher
??????????Mockito.when(obj.methodCall()).thenReturn(result)
?????????????????Stub??????void??????Spy????????
@Test
public void test1() {
// define return value for method getUniqueId()
when(test.getUniqueId()).thenReturn(43);
// use mock in test....
assertEquals(test.getUniqueId()?? 43);
}
@Test
public void testMoreThanOneReturnValue() {
Iterator<String> i= mock(Iterator.class);
when(i.next()).thenReturn("Mockito").thenReturn("rocks");
String result= i.next()+" "+i.next();
//assert
assertEquals("Mockito rocks"?? result);
}
@Test
public void testReturnValueInDependentOnMethodParameter() {
Comparable<Integer> c= mock(Comparable.class);
when(c.compareTo(anyInt())).thenReturn(-1);
//assert
assertEquals(-1?? c.compareTo(9));
}
//return????????answer??????
@Test
public final void answerTest() {
// with thenAnswer():
when(list.add(anyString())).thenAnswer(returnsFirstArg());
// with then() alias:
when(list.add(anyString())).then(returnsFirstArg());
}
?????????????????????Spy????Ч
@Test
public void testLinkedListSpyWrong() {
// Lets mock a LinkedList
List<String> list = new LinkedList<>();
List<String> spy = spy(list);
//??Ч?????????????????????η???????list??
when(spy.get(0)).thenReturn("foo");
assertEquals("foo"?? spy.get(0));
}
??????????Mockito.doReturn(result).when(obj).methodCall()
???????????Stub?????????doAnswer??Stub????
@Test
public void testLinkedListSpyCorrect() {
// Lets mock a LinkedList
List<String> list = new LinkedList<>();
List<String> spy = spy(list);
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
assertEquals("foo"?? spy.get(0));
}
// with doAnswer():
doAnswer(returnsFirstArg()).when(list).add(anyString());
??????when(….).thenReturn(….)???????????????????
Properties properties = mock(Properties.class);
when(properties.get(”Anddroid”)).thenThrow(new IllegalArgumentException(...));
try {
properties.get(”Anddroid”);
fail(”Anddroid is misspelled”);
} catch (IllegalArgumentException ex) {
// good!
}
??????????????Spy
@Test
public void testLinkedListSpyCorrect() {
// Lets mock a LinkedList
List<String> list = new LinkedList<>();
List<String> spy = spy(list);
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
assertEquals("foo"?? spy.get(0));
}
????doAnswer
//???????????
public void getTasks(@NonNull final LoadTasksCallback callback) {...}
interface LoadTasksCallback {
void onTasksLoaded(List<Task> tasks);
void onDataNotAvailable();
}
//stub
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] arg=invocation.getArguments();//???????
TasksDataSource.LoadTasksCallback callback = (TasksDataSource.LoadTasksCallback) arg[0];//0????????????
callback.onTasksLoaded(TASKS);
return null;
}
}).when(mTasksRepository).getTasks(any(TasksDataSource.LoadTasksCallback.class));
???????????
??????????????????ú????
//?????????????????
Mockito.verify(mockUserManager?? Mockito.times(2)).performLogin("xiaochuang"?? "xiaochuang password");
//???????Σ??????д
Mockito.verify(mockUserManager).performLogin("xiaochuang"?? "xiaochuang password");
//????????????
Mockito.verify(test?? atLeastOnce()).someMethod("called at least once");
???????
????ArgumentCaptor
???????????????????????????????????????????л??????????????doAnswer?????д??
???????????hamcrest-library
@Captor
private ArgumentCaptor<List<String>> captor;
@Test
public final void shouldContainCertainListItem() {
List<String> asList = Arrays.asList("someElement_test"?? "someElement");
final List<String> mockedList = mock(List.class);
mockedList.addAll(asList);
verify(mockedList).addAll(captor.capture());
final List<String> capturedArgument = captor.getValue();
assertThat(capturedArgument?? hasItem("someElement"));
}
????InOrder
???????????????????
// A. Single mock whose methods must be invoked in a particular order
List singleMock = mock(List.class);
//using a single mock
singleMock.add("was added first");
singleMock.add("was added second");
//create an inOrder verifier for a single mock
InOrder inOrder = inOrder(singleMock);
//following will make sure that add is first called with "was added first?? then with "was added second"
inOrder.verify(singleMock).add("was added first");
inOrder.verify(singleMock).add("was added second");
// B. Multiple mocks that must be used in a particular order
List firstMock = mock(List.class);
List secondMock = mock(List.class);
//using mocks
firstMock.add("was called first");
secondMock.add("was called second");
//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock?? secondMock);
//following will make sure that firstMock was called before secondMock
inOrder.verify(firstMock).add("was called first");
inOrder.verify(secondMock).add("was called second");
// Oh?? and A + B can be mixed together at will
????@InjectMocks
?????????????й???????Mock????????????????????????
public ArticleManager(User user?? ArticleDatabase database) {
super();
this.user = user;
this.database = database;
}
@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest {
@Mock
ArticleDatabase database;
@Mock
User user;
@InjectMocks
private ArticleManager manager;
}
????Espresso??UI????
??????
???·???
??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44???????????????
2021/9/17 15:19:29???·???????·
2021/9/14 15:42:25?????????????
2021/5/28 17:25:47??????APP??????????
2021/5/8 17:01:11