JUint+Mockito 单元测试总结~

JUnit是单元测试框架,很棒的。

而Mockito是一种生成模拟对象——“假对象”工具。

一般是将两者结合起来进行测试。

官方例子是

List mock = mock( List.class );  
when( mock.get(0) ).thenReturn( 1 );  
assertEquals( "预期返回1", 1, mock.get( 0 ) );// mock.get(0) 返回 1

在maven项目中,先增加依赖。

		<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
			<dependency>
		      <groupId>org.mockito</groupId>
		      <artifactId>mockito-all</artifactId>
		      <version>1.9.5</version>
		      <scope>test</scope>
		    </dependency>

当然会有junit的依赖

		<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
			<dependency>
		      <groupId>org.mockito</groupId>
		      <artifactId>mockito-all</artifactId>
		      <version>1.9.5</version>
		      <scope>test</scope>
		    </dependency>
为了代码的简介,静态导入包

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

在示例代码中

	@Test
	public void test() {

		List mock = mock(List.class);
		mock.add(1);
		mock.clear();

		verify(mock).add(1);
		verify(mock).clear();

		// when(mock.get(0)).thenReturn(1);
		// assertEquals("预期1",1,mock.get(0));

	}

大致的意思就是进行add方法和clear方法的验证。

对返回规则的验证

	@Test
	public void whenThenReturn() {
		// mock一个Iterator类
		Iterator iterator = mock(Iterator.class);
		// 假设iterator调用next()时,第一次返回hello,第n次返回world;
		when(iterator.next()).thenReturn("hello").thenReturn("world");
		// 使用mock的对象
		String resString = iterator.next() + " " + iterator.next() + " "
				+ iterator.next();

		assertEquals("hello world world", resString);

	}
如果没有返回值的,会用到doNothing()

doNothing().when(obj).notify();  
// 或直接  
when(obj).notify(); 

可以强制抛出异常,对异常捕捉进行test

	@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();
	}
上面,在调用outputStream的close方法时,抛出IO异常,对齐进行验证。

关注Verify
前面提到的 when(……).thenReturn(……) 属于状态测试,某些时候,测试不关心返回结果,而是侧重方法有否被正确的参数调用过,这时候就应该使用 验证方法了。从概念上讲,就是和状态测试所不同的“行为测试”了。

一旦使用 mock() 对模拟对象打桩,意味着 Mockito 会记录着这个模拟对象调用了什么方法,还有调用了多少次。最后由用户决定是否需要进行验证,即 verify() 方法。

正如前面所示的例子,可以校验调用的次数。

	@Test
	public void verify_test() {
		Map mockmap = mock(Map.class);
		when(mockmap.get("c")).thenReturn("杭州");
		//关注参数是否有传入
		verify(mockmap).get(Matchers.eq("c"));
		//关注调用的次数
		verify(mockmap,times(2));
	}

Mockito除了times(N),还有以下几个

  • never() 没有被调用,相当于 times(0)
  • atLeast(N) 至少被调用 N 次
  • atLeastOnce() 相当于 atLeast(1)
  • atMost(N) 最多被调用 N 次


所谓 Mock 与 Stub 打桩,其实它们之间不能互为其表。但 Mockito 语境中则  Stub 和 Mock 对象同时使用的 。因为它既可以设置方法调用返回值,又可以验证方法的调用。有关 stub 和 mock 的详细论述请见 Martin Fowler 大叔的文章 《Mocks Aren't Stub》

下面不想整理了,参考

点击打开链接


Spy的使用

意思就是可以修改真实对象的某些方法,不用更改他的基本行为特性,类似AOP。

List list = new LinkedList();    
List spy = spy(list);    
    
//optionally, you can stub out some methods:    
when(spy.size()).thenReturn(100);    
     
//using the spy calls <b>real</b> methods    
spy.add("one");    
spy.add("two");    
     
//prints "one" - the first element of a list    
System.out.println(spy.get(0));    
     
//size() method was stubbed - 100 is printed    
System.out.println(spy.size());    
     
//optionally, you can verify    
verify(spy).add("one");    
verify(spy).add("two");

spy 保留了 list 的大部分功能,只是将它的 size() 方法改写了。

其他

可以在刚刚开始的时候,通过

@Before

的注解来进行前期的初始化工作。

public class ArticleManagerTest {  
    @Mock private ArticleCalculator calculator;  
    @Mock private ArticleDatabase database;  
    @Mock private UserProvider userProvider;  
  
    @Before public void setup() {  
        MockitoAnnotations.initMocks(testClass);  
    }  
} 



貌似 Mockito 的注解都比较强大,有待以后再看看:

《学习Mockito - Mockito对Annotation的支持》, http://jilen.iteye.com/blog/1427368


下面,有时间再整理。


©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页