首页 > 代码库 > mockito框架

mockito框架

参考自

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,是测试类更具有可读性,我们可以使用下面的注解方式来快速模拟对象:

 

[java] view plain copy print?技术分享技术分享
  1. @Mock  
  2. private List mockList;  
技术分享
	@Mock	private List mockList;

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

 

 

[java] view plain copy print?技术分享技术分享
  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的代码

 

 

[java] view plain copy print?技术分享技术分享
  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

 

[java] view plain copy print?技术分享技术分享
  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框架