@Mock(answer = Answers.RETURNS_DEEP_STUBS)
package com.test.junitTest;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
public class MockitoTest {
@Test
public void verify_behaviour() {
// 模拟创建一个List对象
List mock = mock(List.class);
// 使用mock的对象
mock.add(1);
mock.clear();
// 验证add(1)和clear()行为是否发生
verify(mock).add(1);
verify(mock).clear();
}
@Test
public void when_thenReturn() {
// mock一个Iterator类
Iterator iterator = mock(Iterator.class);
// 预设当iterator调用next()时第一次返回hello,第n次都返回world
when(iterator.next()).thenReturn("hello").thenReturn("world");
// 使用mock的对象
String result = iterator.next() + " " + iterator.next() + " " + iterator.next();
// 验证结果
assertEquals("hello world world", result);
}
@Test(expected = IOException.class)
public void when_thenThrow() throws IOException {
OutputStream outputStream = mock(OutputStream.class);
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
// 预设当流关闭时抛出异常
doThrow(new IOException()).when(outputStream).close();
outputStream.close();
}
@Test
public void returnsSmartNullsTest() {
List mock = mock(List.class, RETURNS_SMART_NULLS);
// List mock = mock(List.class);
// 使用RETURNS_SMART_NULLS参数创建的mock对象,不会抛出NullPointerException异常。另外控制台窗口会提示信息“SmartNull returned
// by unstubbed get() method on mock”
// System.out.println(mock.toArray().length);
}
@Test
public void with_arguments() {
Comparable comparable = mock(Comparable.class);
// 预设根据不同的参数返回不同的结果
when(comparable.compareTo("Test")).thenReturn(1);
when(comparable.compareTo("Omg")).thenReturn(2);
assertEquals(1, comparable.compareTo("Test"));
assertEquals(2, comparable.compareTo("Omg"));
// 对于没有预设的情况会返回默认值
assertEquals(0, comparable.compareTo("Not stub"));
}
@Test
public void with_unspecified_arguments() {
List list = mock(List.class);
// 匹配任意参数
when(list.get(anyInt())).thenReturn(1);
when(list.contains(argThat(new IsValid()))).thenReturn(true);
assertEquals(1, list.get(1));
assertEquals(1, list.get(999));
assertTrue(list.contains(1));
assertTrue(!list.contains(3));
}
private class IsValid extends ArgumentMatcher<List> {
@Override
public boolean matches(Object o) {
return o.equals(1) || o.equals(2);
}
}
@Test
public void all_arguments_provided_by_matchers() {
Comparator comparator = mock(Comparator.class);
comparator.compare("nihao", "hello");
// 如果你使用了参数匹配,那么所有的参数都必须通过matchers来匹配
verify(comparator).compare(anyString(), eq("hello"));
// 下面的为无效的参数匹配使用
// verify(comparator).compare(anyString(), "hello");
}
@Test
public void argumentMatchersTest() {
// 创建mock对象
List<String> mock = mock(List.class);
// argThat(Matches<T> matcher)方法用来应用自定义的规则,可以传入任何实现Matcher接口的实现类。
when(mock.addAll(argThat(new IsListofTwoElements()))).thenReturn(true);
mock.addAll(Arrays.asList("one", "two", "three"));
// IsListofTwoElements用来匹配size为2的List,因为例子传入List为三个元素,所以此时将失败。
verify(mock).addAll(argThat(new IsListofTwoElements()));
}
class IsListofTwoElements extends ArgumentMatcher<List> {
public boolean matches(Object list) {
return ((List) list).size() == 3;
}
}
@Test
public void unstubbed_invocations() {
// mock对象使用Answer来对未预设的调用返回默认期望值
List mock = mock(List.class, new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return 999;
}
});
// 下面的get(1)没有预设,通常情况下会返回NULL,但是使用了Answer改变了默认期望值
assertEquals(999, mock.get(1));
// 下面的size()没有预设,通常情况下会返回0,但是使用了Answer改变了默认期望值
assertEquals(999, mock.size());
}
@Test
public void answer_with_callback() {
List mockList = mock(List.class);
// 使用Answer来生成我们我们期望的返回
when(mockList.get(anyInt())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return "hello world:" + args[0];
}
});
assertEquals("hello world:0", mockList.get(0));
assertEquals("hello world:999", mockList.get(999));
}
@Test(expected = RuntimeException.class)
public void consecutive_calls() {
List mockList = mock(List.class);
// 模拟连续调用返回期望值,如果分开,则只有最后一个有效
when(mockList.get(0)).thenReturn(0);
when(mockList.get(0)).thenReturn(1);
when(mockList.get(0)).thenReturn(2);
when(mockList.get(1)).thenReturn(0).thenReturn(1).thenThrow(new RuntimeException());
assertEquals(2, mockList.get(0));
assertEquals(2, mockList.get(0));
assertEquals(0, mockList.get(1));
assertEquals(1, mockList.get(1));
// 第三次或更多调用都会抛出异常
mockList.get(1);
}
}
@RunWith(MockitoJUnitRunner.class)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>junitTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>junitTest</name>
<dependencies>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
ReflectionTestUtils.setField