码迷,mamicode.com
首页 > 其他好文 > 详细

mockito框架

时间:2016-09-01 00:07:43      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

参考自

http://www.cnblogs.com/silence-hust/p/5017233.html

http://blog.csdn.net/sdyy321/article/details/38757135

首先创建一个maven工程

技术分享

在pom文件中,存在如下依赖

      <dependencies>
             <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>

 1、验证行为是否发生

 

@Test
    public void mockedList(){
        List mockedList = mock(List.class);
        mockedList.add("one");
        mockedList.clear();
        //验证add("one")和clear()行为是否发生
        verify(mockedList).add("one");
        verify(mockedList).clear();
    }

2、验证返回值

 

@Test
    public void two(){
        //模拟创建一个List对象
        LinkedList mockLinkedList = mock(LinkedList.class);
 
        //打桩,当LinkedList调用get(0)方法时,第一次返回hello,第二次n次返回world
        when(mockLinkedList.get(0)).thenReturn("hello").thenReturn("world");
        String result = mockLinkedList.get(0) + " " + mockLinkedList.get(0) + " " + mockLinkedList.get(0);  
 
        //使用mock对象
        System.out.println(mockLinkedList.get(0));
        System.out.println(mockLinkedList.get(0));
        System.out.println(mockLinkedList.get(0));
       
        assertEquals("hello world world",result);  
    }

 

这里注意所有的方法都会有返回值,如果没有设置返回值,那么就会返回null或者空集、适当的类型。 Stubbing可以被重写,也就是同一个参数方法可以放回不同的值,但是以最后一次设置的值为标准。一旦被 Stubbed,无论方法被调用多少次,都只会返回Stubbed value。最后一次最重要原则。

第一次运行打印 hello world world,这是第二次运行测试打印 world world world。

3、参数匹配

 

@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"));  
    }  

除了匹配给定参数外,还可以使用参数匹配器 argumentMatchers,更加灵活

@Test  
    public void argumentMatchersTest(){  
        List list = mock(List.class);  
        //匹配任意int类型的值 
        when(list.get(anyInt())).thenReturn(1);
        assertEquals(1, list.get(1));  
        verify(list).get(anyInt());
        assertEquals(1, list.get(999)); 
    }  

若方法中的某一个参数使用了matcher,则所有的参数都必须使用matcher:

@Test  
    public void argumentMatchersTest2(){  
        Map map = mock(Map.class);  
        //匹配任意参数  
        when(map.put(anyInt(),anyString())).thenReturn("world");  
        assertEquals("world", map.put(1,"hello"));
        //以下三种验证都可通过测试
        verify(map).put(anyInt(),anyString());
        verify(map).put(anyInt(),eq("hello"));
        verify(map).put(eq(1),eq("hello"));
    } 

4、验证调用次数

@Test
    public void three(){
        List mockedList = mock(List.class);
        mockedList.add(1);
        mockedList.add(2);
        mockedList.add(2);
        mockedList.add(3);
        mockedList.add(3);
        mockedList.add(3);
        //验证是否被调用一次,等效于下面的times(1),默认的,可以不写
        verify(mockedList).add(1);
        verify(mockedList,times(1)).add(1);
        //验证是否被调用2次 
        verify(mockedList,times(2)).add(2);
        //验证是否被调用3次 
        verify(mockedList,times(3)).add(3);
        //验证是否从未被调用过
        verify(mockedList,never()).add(4);
        //验证至少调用一次
        verify(mockedList,atLeastOnce()).add(1);
        //验证至少调用2次
        verify(mockedList,atLeast(2)).add(2);
        //验证至多调用3次
        verify(mockedList,atMost(3)).add(3);
    }

5、模拟抛出异常

@Test(expected = IOException.class)  
    public void when_thenThrow() throws IOException {  
        OutputStream outputStream = mock(OutputStream.class);  //预设当流关闭时抛出异常 ,因为close()返回类型为void,采用了doThrow 形式
        doThrow(new IOException()).when(outputStream).close();
        outputStream.close();  
    }
    

6、验证执行的顺序

@Test
    public void four(){
        List firstList = mock(List.class);
        List secondList = mock(List.class);
        //using mocks
        firstList.add("was called first one mock");
        firstList.add("was called second one mock");
        secondList.add("was called third one mock");
        secondList.add("was called fourth one mock");
        //create inOrder object passing any mocks that need to be verified in order
        
       // InOrder indOrder = inOrder(firstList,secondList);
        InOrder indOrder = inOrder(secondList,firstList);
       //实际上两种顺序都通过测试了
      
        indOrder.verify(firstList).add("was called first one mock");
        indOrder.verify(firstList).add("was called second one mock");
        indOrder.verify(secondList).add("was called third one mock");
        indOrder.verify(secondList).add("was called fourth one mock");
 
    }

7、验证零互动

@Test  
    public void verify_interaction(){  
        List list = mock(List.class);  
        List list2 = mock(List.class);  
        List list3 = mock(List.class);  
        list.add(1);  
        verify(list).add(1);  
        verify(list,never()).add(2);  
        //验证零互动行为  
        verifyZeroInteractions(list2,list3);  
    }  

8、找出冗余的互动(即未被验证到的)

@Test
    public void find_redundant_interaction(){  
        List list = mock(List.class);  
        list.add(1);  
        list.add(2);  
        verify(list,times(2)).add(anyInt());  
       //检查是否有未被验证的互动行为,因为add(1)和add(2)都会被上面的anyInt()验证到,所以下面的代码会通过  
        verifyNoMoreInteractions(list);  
      
       //下面因为只验证了add(1),add(2)没有被验证,所以下面的代码会失败抛出异常  
       //  List list2 = mock(List.class);  
       // list2.add(1);  
       // list2.add(2);  
       //verify(list2).add(1);  
       // verifyNoMoreInteractions(list2);  
    }  

9、使用注解来快速模拟

 

在上面的测试中我们在每个测试方法里都mock了一个List对象,为了避免重复的mock,是测试类更具有可读性,我们可以使用下面的注解方式来快速模拟对象:

 

  1. @Mock  
  2. private List mockList;  
技术分享
	@Mock
	private List mockList;

OK,我们再用注解的mock对象试试

 

 

  1. @Test  
  2. public void shorthand(){  
  3.     mockList.add(1);  
  4.     verify(mockList).add(1);  
  5. }  
技术分享
	@Test
	public void shorthand(){
		mockList.add(1);
		verify(mockList).add(1);
	}

运行这个测试类你会发现报错了,mock的对象为NULL,为此我们必须在基类中添加初始化mock的代码

 

 

  1. public class MockitoExample2 {  
  2.     @Mock  
  3.     private List mockList;  
  4.   
  5.     public MockitoExample2(){  
  6.         MockitoAnnotations.initMocks(this);  
  7.     }  
  8.   
  9.     @Test  
  10.     public void shorthand(){  
  11.         mockList.add(1);  
  12.         verify(mockList).add(1);  
  13.     }  
  14. }  
技术分享
public class MockitoExample2 {
	@Mock
	private List mockList;

	public MockitoExample2(){
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void shorthand(){
		mockList.add(1);
		verify(mockList).add(1);
	}
}

 

或者使用built-in runner:MockitoJUnitRunner

 

  1. @RunWith(MockitoJUnitRunner.class)  
  2. public class MockitoExample2 {  
  3.     @Mock  
  4.     private List mockList;  
  5.   
  6.     @Test  
  7.     public void shorthand(){  
  8.         mockList.add(1);  
  9.         verify(mockList).add(1);  
  10.     }  
  11. }  
技术分享
@RunWith(MockitoJUnitRunner.class)
public class MockitoExample2 {
	@Mock
	private List mockList;

	@Test
	public void shorthand(){
		mockList.add(1);
		verify(mockList).add(1);
	}
}

 

更多的注解还有@Captor,@Spy,@InjectMocks

 

mockito框架

标签:

原文地址:http://www.cnblogs.com/kanhaiba/p/5454280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!