`
yxj1141
  • 浏览: 2159 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

5分钟了解Mockito

阅读更多

 

一、什么是mock测试,什么是mock对象?

 

先来看看下面这个示例:

从上图可以看出如果我们要对A进行测试,那么就要先把整个依赖树构建出来,也就是BCDE的实例。

 

一种替代方案就是使用mocks

从图中可以清晰的看出

mock对象就在调试期间用来作为真实对象的替代品

mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。

知道什么是mock测试后,那么我们就来认识一下mock框架---Mockito

 

二、什么是Mockito

除了有一个好记的名字外,Mockito尝试用不一样的方法做mocking测试,是简单轻量级能够替代EasyMock的框架。使用简单,测试代码可读性高,丰富的文档包含在javadoc中,直接在IDE中可查看文档,实例,说明。更多信息:http://code.google.com/p/mockito/

 

三、Stub和Mock

相同点:Stub和Mock对象都是用来模拟外部依赖,使我们能控制。

不同点:而stub完全是模拟一个外部依赖,用来提供测试时所需要的测试数据。而mock对象用来判断测试是否能通过,也就是用来验证测试中依赖对象间的交互能否达到预期。在mocking框架中mock对象可以同时作为stub和mock对象使用,两者并没有严格区别。 更多信息:http://martinfowler.com/articles/mocksArentStubs.html

 

四、mockito入门实例

Maven依赖:(没用maven管理的直接忽略)

 

Xml代码 
  1. <dependencies>     
  2. <dependency>     
  3. <groupId>org.mockito</groupId>     
  4. <artifactId>mockito-all</artifactId>     
  5. <version>1.8.5</version>     
  6. <scope>test</scope>     
  7. </dependency>     
  8. </dependencies>  
  1. <dependencies>    
  2. <dependency>    
  3. <groupId>org.mockito</groupId>    
  4. <artifactId>mockito-all</artifactId>    
  5. <version>1.8.5</version>    
  6. <scope>test</scope>    
  7. </dependency>    
  8. </dependencies>  

 

Java代码 
  1. import static org.mockito.Mockito.*;   
  2.   
  3. import java.util.List;   
  4.   
  5. import org.junit.Assert;   
  6. import org.junit.Test;   
  7.   
  8. /**  
  9.  *   
  10.  * @author lzjun  
  11.  * @version 0.1  
  12.  * @date 2012-5-5  
  13.  * {@link http://weibo.com/u/1697702241}   
  14.  *  
  15.  */  
  16. public class SimpleTest {   
  17.            
  18.     @Test  
  19.     public void simpleTest(){   
  20.            
  21.         //创建mock对象,参数可以是类,也可以是接口   
  22.         List<String> list = mock(List.class);   
  23.            
  24.         //设置方法的预期返回值   
  25.         when(list.get(0)).thenReturn("helloworld");   
  26.        
  27.         String result = list.get(0);   
  28.            
  29.         //验证方法调用(是否调用了get(0))   
  30.         verify(list).get(0);   
  31.            
  32.         //junit测试   
  33.         Assert.assertEquals("helloworld", result);   
  34.     }   
  35. }  
  1. import static org.mockito.Mockito.*;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.junit.Assert;  
  6. import org.junit.Test;  
  7.   
  8. /** 
  9.  *  
  10.  * @author lzjun 
  11.  * @version 0.1 
  12.  * @date 2012-5-5 
  13.  * {@link http://weibo.com/u/1697702241}  
  14.  * 
  15.  */  
  16. public class SimpleTest {  
  17.           
  18.     @Test  
  19.     public void simpleTest(){  
  20.           
  21.         //创建mock对象,参数可以是类,也可以是接口  
  22.         List<String> list = mock(List.class);  
  23.           
  24.         //设置方法的预期返回值  
  25.         when(list.get(0)).thenReturn("helloworld");  
  26.       
  27.         String result = list.get(0);  
  28.           
  29.         //验证方法调用(是否调用了get(0))  
  30.         verify(list).get(0);  
  31.           
  32.         //junit测试  
  33.         Assert.assertEquals("helloworld", result);  
  34.     }  
  35. }  

好了,五分钟差不多了,还想继续了解那就可以往下面看

 

创建mock对象不能对final,Anonymous ,primitive类进行mock。

 

可对方法设定返回异常

 

Java代码 
  1. when(list.get(1)).thenThrow(new RuntimeException("test excpetion"));  
  1. when(list.get(1)).thenThrow(new RuntimeException("test excpetion"));  

 

stubbing另一种语法(设置预期值的方法),可读性不如前者

Java代码 
  1. doReturn("secondhello").when(list).get(1);  
  1. doReturn("secondhello").when(list).get(1);  

没有返回值的void方法与其设定(支持迭代风格,第一次调用donothing,第二次dothrow抛出runtime异常)

Java代码 
  1. doNothing().doThrow(new RuntimeException("void exception")).when(list).clear();   
  2. list.clear();   
  3. list.clear();   
  4. verify(list,times(2)).clear();  
  1. doNothing().doThrow(new RuntimeException("void exception")).when(list).clear();  
  2. list.clear();  
  3. list.clear();  
  4. verify(list,times(2)).clear();  

 

五、参数匹配器(Argument Matcher)

Matchers类内加你有很多参数匹配器  anyInt、anyString、anyMap.....Mockito类继承于Matchers,Stubbing时使用内建参数匹配器,下例:

 

Java代码 
  1. @Test  
  2. public void argumentMatcherTest(){   
  3.        
  4.     List<String> list = mock(List.class);   
  5.        
  6.     when(list.get(anyInt())).thenReturn("hello","world");   
  7.        
  8.     String result = list.get(0)+list.get(1);   
  9.        
  10.     verify(list,times(2)).get(anyInt());   
  11.        
  12.     Assert.assertEquals("helloworld", result);   
  13.        
  14. }  
  1. @Test  
  2. public void argumentMatcherTest(){  
  3.       
  4.     List<String> list = mock(List.class);  
  5.       
  6.     when(list.get(anyInt())).thenReturn("hello","world");  
  7.       
  8.     String result = list.get(0)+list.get(1);  
  9.       
  10.     verify(list,times(2)).get(anyInt());  
  11.       
  12.     Assert.assertEquals("helloworld", result);  
  13.       
  14. }  

 

 需要注意的是:如果使用参数匹配器,那么所有的参数都要使用参数匹配器,不管是stubbing还是verify的时候都一样。

 

Java代码 
  1. @Test  
  2. public void argumentMatcherTest2(){   
  3.        
  4.     Map<Integer,String> map = mock(Map.class);   
  5.     when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替换成"hello"就会报错   
  6.     map.put(1"world");   
  7.     verify(map).put(eq(1), eq("world")); //eq("world")替换成"world"也会报错   
  8.        
  9. }   
  1. @Test  
  2. public void argumentMatcherTest2(){  
  3.       
  4.     Map<Integer,String> map = mock(Map.class);  
  5.     when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替换成"hello"就会报错  
  6.     map.put(1"world");  
  7.     verify(map).put(eq(1), eq("world")); //eq("world")替换成"world"也会报错  
  8.       
  9. }  

 

 六、方法调用的验证(具体的调用次数、至少一次,一次也没有)

 

Java代码 
  1. @Test  
  2. public void verifyInvocate(){   
  3.        
  4.     List<String> mockedList = mock(List.class);   
  5.     //using mock    
  6.      mockedList.add("once");   
  7.      mockedList.add("twice");   
  8.      mockedList.add("twice");   
  9.         
  10.      mockedList.add("three times");   
  11.      mockedList.add("three times");   
  12.      mockedList.add("three times");   
  13.         
  14.      /**  
  15.       * 基本的验证方法  
  16.       * verify方法验证mock对象是否有没有调用mockedList.add("once")方法  
  17.       * 不关心其是否有返回值,如果没有调用测试失败。  
  18.       */  
  19.      verify(mockedList).add("once");    
  20.      verify(mockedList, times(1)).add("once");//默认调用一次,times(1)可以省略   
  21.         
  22.         
  23.      verify(mockedList, times(2)).add("twice");   
  24.      verify(mockedList, times(3)).add("three times");   
  25.         
  26.      //never()等同于time(0),一次也没有调用   
  27.      verify(mockedList, times(0)).add("never happened");   
  28.         
  29.      //atLeastOnece/atLeast()/atMost()   
  30.      verify(mockedList, atLeastOnce()).add("three times");   
  31.      verify(mockedList, atLeast(2)).add("twice");   
  32.      verify(mockedList, atMost(5)).add("three times");   
  33.   
  34. }  
  1. @Test  
  2. public void verifyInvocate(){  
  3.       
  4.     List<String> mockedList = mock(List.class);  
  5.     //using mock   
  6.      mockedList.add("once");  
  7.      mockedList.add("twice");  
  8.      mockedList.add("twice");  
  9.        
  10.      mockedList.add("three times");  
  11.      mockedList.add("three times");  
  12.      mockedList.add("three times");  
  13.        
  14.      /** 
  15.       * 基本的验证方法 
  16.       * verify方法验证mock对象是否有没有调用mockedList.add("once")方法 
  17.       * 不关心其是否有返回值,如果没有调用测试失败。 
  18.       */  
  19.      verify(mockedList).add("once");   
  20.      verify(mockedList, times(1)).add("once");//默认调用一次,times(1)可以省略  
  21.        
  22.        
  23.      verify(mockedList, times(2)).add("twice");  
  24.      verify(mockedList, times(3)).add("three times");  
  25.        
  26.      //never()等同于time(0),一次也没有调用  
  27.      verify(mockedList, times(0)).add("never happened");  
  28.        
  29.      //atLeastOnece/atLeast()/atMost()  
  30.      verify(mockedList, atLeastOnce()).add("three times");  
  31.      verify(mockedList, atLeast(2)).add("twice");  
  32.      verify(mockedList, atMost(5)).add("three times");  
  33.   
  34. }  
分享到:
评论

相关推荐

    Mockito-Programming-Cookbook

    #### 五、Mockito 在 Spring 测试中的应用 1. **Spring 测试集成**: - Spring 提供了与 Mockito 结合使用的测试支持。 - 可以通过 Spring 的测试框架来整合 Mockito,实现更高效的单元测试。 2. **创建项目**:...

    Mockito的重要入门资料

    ### Mockito的重要入门资料 #### 学习目标与背景 ...通过上述介绍,我们不仅了解了Mockito的基本用法,还深入探讨了其高级特性。这些知识点将极大地帮助开发者更高效地编写单元测试,提高软件产品的质量和可维护性。

    Mocks, Mockito, and Spock

    通过本文的介绍,我们了解了Mocks的基本概念及其在单元测试中的重要作用,并深入探讨了如何使用Mockito来有效地进行模拟对象的创建、Stubbing以及验证行为等功能。Mockito的强大功能和简洁API使其成为Java开发者进行...

    Mockito入门

    在入门Mockito时,首先需要了解的是基本术语: 1. **Mock**:这是模拟对象,它不会执行任何实际操作,而是记录下对它的调用,供后续验证。 2. **Stubbing**:这是指为mock对象设定预定义的返回值或行为,当特定的...

    springboot + mockito 使用示例代码-原创

    首先,让我们了解什么是单元测试。单元测试是一种软件开发方法,其中我们对程序的各个小部分(称为“单元”)进行独立测试,以确保它们按照预期工作。在Spring Boot项目中,这通常涉及测试单个服务方法或控制器。 ...

    Mastering Unit Testing Using Mockito and JUnit.pdf

    3. Mockito基础:了解Mockito的基本概念,如何创建mock和spy对象,以及使用when()和verify()方法。 4. 高级Mockito技巧:包括Stubbing、Argument Matchers、 verification in order、nested mocks等。 5. 测试驱动...

    Practical Unit Testing with TestNG and Mockito

    了解测试方法执行前后的各个阶段(如初始化、执行、清理)对于编写高效、准确的测试非常重要。TestNG为此提供了丰富的注解支持。 #### 结论 通过本章的学习,读者应该已经掌握了如何使用TestNG和Mockito来进行有效...

    Mockito+junit5搞定单元测试

    通过以上的介绍,我们了解了如何使用 Mockito 和 JUnit 5 搭配进行单元测试。Mockito 提供了强大的模拟功能,使得测试更加灵活和可控;而 JUnit 5 提供了丰富的测试注解和功能,让编写和组织测试变得更加便捷。结合...

    Packt Publishing Mastering Unit Testing Using Mockito and JUnit (2014)

    - **高级 Mockito 特性**:了解 Mockito 提供的一些高级特性,如验证方法调用顺序、设置模拟对象的行为等。 通过以上知识点的学习,读者可以全面掌握如何使用 JUnit 4 和 Mockito 来构建高效、可靠的单元测试。这...

    Testing Java with JUnit 5 & Mockito学习资料

    JUnit作为Java领域最常用的测试框架,已经发展到了第五版(JUnit 5),带来了许多新特性和改进。本学习资料主要围绕使用JUnit 5进行单元测试,并结合Mockito库进行模拟对象的测试。 首先,让我们了解一下如何将...

    Java_Mockito初学者教程.zip

    这个初学者教程将引导你深入了解Mockito的基本概念和用法。 首先,了解单元测试的重要性是至关重要的。单元测试是软件开发过程中的一个关键部分,它允许程序员对代码的各个独立部分进行验证,确保它们按预期工作。...

    powermock-mockito-junit-1.6.2.zip

    - 示例代码或文档:可能包含使用PowerMock和Mockito的示例测试用例,帮助开发者了解如何在实际项目中集成和使用这些库。 在使用PowerMock-Mockito-JUnit-1.6.2进行单元测试时,开发者需要按照以下步骤操作: 1. ...

    mockito单元测试

    通过上述介绍,我们不仅了解了Mockito的基本概念,还学习了如何使用它来模拟依赖组件并验证方法调用。希望这些知识能够帮助你在日常开发中更好地利用Mockito进行单元测试,提高代码质量和可维护性。

    【mockito实战】mockito+junit搞定单元测试,包含测试代码及被测试项目

    首先,让我们深入了解一下 Mockito。Mockito 提供了模拟(mocking)和验证(verification)的功能,模拟对象可以代替真实的依赖项,这样我们就可以控制它们的行为并在测试中精确地定义它们的响应。例如,如果我们...

    mockito

    Mockito 是一个流行的 Java 单元...通过 `mockito-master` 压缩包,你可以深入研究其源码,了解其实现原理,以及如何在实际项目中高效地利用它。同时,文档和示例项目可以帮助你快速上手并熟练掌握 Mockito 的用法。

    MockitoDemo:使用 Mockito 在 Java 中进行 Mocking 入门

    Mockito 是一个流行的 Java 单元测试...通过这个 MockitoDemo,你可以了解到如何在实际项目中使用 Mockito 进行单元测试,以及如何利用它来提高测试的质量和效率。同时,这也是学习和掌握单元测试及模拟技术的好方式。

    mockito-sample:在JUnit测试用例中如何使用Mockito创建模拟对象的快速示例

    通过学习这个示例,开发者可以了解如何在实际项目中使用 Mockito 和 JUnit 进行单元测试,包括如何创建模拟对象、预定义行为、验证方法调用等。这对于提高代码质量、确保功能正确性至关重要,特别是在大型复杂项目中...

    android-test-demo:使用 Dagger、Mockito、Junit 进行 Android 测试

    5. **项目结构**:`android-test-demo-master`这个文件名表明项目是基于Git仓库的主分支。通常,这样的项目会包含以下几个部分: - `src/main`: 主代码目录,包括`java`和`res`子目录,分别存放Java源码和资源文件...

    My-Mockito-Framework:Mockito在内部如何工作?

    例如,`anyInt()`、`eq(5)`等,它们允许你在预设行为和验证调用时使用通配符或具体值来匹配参数。 在Mockito框架中,`@Mock`和`@Spy`注解可以用于字段或方法参数上,以自动初始化模拟或间谍对象。`@InjectMocks`...

    Mockito1

    了解并熟练掌握Mockito,可以帮助我们编写更高效、更可靠的单元测试,提升软件质量。在实际项目中,可以根据需求进一步学习Mockito的高级特性,如Argument Captor、Spying等,以满足更复杂的测试场景。

Global site tag (gtag.js) - Google Analytics