zoukankan      html  css  js  c++  java
  • Mockito框架Mock Void方法

    在编写代码时,总是有方法返回void,并且在某个测试用例需要模拟void方法。那么我们如何去做呢?让我们一起在下面的内容中使用Mockito完成这个需求。

    • Mockito是用于编写单元测试的最著名的模拟框架之一。

    为什么模拟void方法

    假设我们有一个方法A,在此方法中,使用了另一个void方法B。现在,当要为该方法编写测试用例时,我们如何测试B方法被调用?另外,是否将正确的参数传递给B方法?在这种情况下,Mockito可以帮助我们解决这个问题。

    让我们举个例子,我们有一个UserService类。在此类中,我们有一个updateName()方法。

    public UserService{
    
       public void updateName(Long id, String name){
          userRepository.updateName(id, name);
       }
    }
    

    现在,我们要为UserService类编写单元测试并模拟userRepository。但是,在此测试用例中,我们唯一需要验证的是使用正确的参数集调用了userRepository中的updateName()方法。为此,我们需要模拟updateName()方法,捕获参数并验证参数。

    这里要注意的最重要的是,我们不能仅仅使用Mockitowhen-then机制来模拟void方法。因为,Mockitowhen()方法适用于返回值,而方法返回值是void时则不适用。

    如何在Mockito中模拟void方法

    Mockito中,我们可以使用不同的方法来调用实例方法或模拟void方法。根据要求使用其中一个选项:

    • doNothing():完全忽略对void方法的调用,这是默认
    • doAnswer():在调用void方法时执行一些运行时或复杂的操作
    • doThrow():调用模拟的 void方法时引发异常
    • doCallRealMethod():不要模拟并调用真实方法

    使用doNothing()

    如果我们只想完全忽略void方法调用,则可以使用doNothing()

    在测试用例中,对于模拟对象的每种方法,doNothing是默认行为。因此,如果不想验证参数,则使用doNothing是完全可以的。

    doNothing()用于void方法的Demo

    @Test
    public void test001() {
       doNothing().when(mockedUserRepository).updateName(anyLong(),anyString());
     
       userService.updateName(1L,"FunTester");
         
       verify(mockedUserRepository, times(1)).updateName(1L,"FunTester");
    }
    

    不对空方法使用doNothing()

    @Test
    public void test002() {
     
       userService.updateName(1L,"FunTester");
         
       verify(mockedUserRepository, times(1)).updateName(1L,"FunTester");
    }
    
    

    使用doNothing()进行参数捕获的示例

    @Test
    public void testUpdateNameUsingArgumentCaptor() {
     
       ArgumentCaptor<Long> idCapture = ArgumentCaptor.forClass(Long.class);
       ArgumentCaptor<String> nameCapture = ArgumentCaptor.forClass(String.class);
       doNothing().when(mockedUserRepository).updateName(idCapture.capture(),nameCapture.capture());
      
       userService.updateName(1L,"FunTester");
         
       assertEquals(1L, idCapture.getValue());
       
       assertEquals("FunTester", nameCapture.getValue());
    }
    

    将doAnswer()用于void方法

    如果我们不想调用真实方法,则需要执行一些运行时操作,请使用doAnswer()

    下面是使用doAnswer()打印并验证参数的Demo:

    @Test
    public void testUpdateNameUsingDoAnswer() {
       doAnswer(invocation -> {
          long id = invocation.getArgument(0);
          String name = invocation.getArgument(1);
          System.out.println("called for id: "+id+" and name: "+name);
     
          assertEquals(1L, id);
          assertEquals("FunTester", name);
     
          return null;
    }).when(mockedUserRepository).updateName(anyLong(),anyString());
     
       userService.updateName(1L,"FunTester");
       verify(mockedUserRepository, times(1)).updateName(1L,"FunTester");
    }
    

    使用doThrow()引发异常

    如果要在调用方法时引发异常,则可以使用嘲笑的doThrow()方法。

    让我们举一个例子:当使用null作为id调用updateName()方法时,我们将引发InvalidParamException

    @Test(expected = InvalidParamException.class)
    public void testUpdateNameThrowExceptionWhenIdNull() {
       doThrow(new InvalidParamException())
          .when(mockedUserRepository).updateName(null,anyString();
       userService.updateName(null,"FunTester");
    }
    

    使用doCallRealMethod()进行真实方法调用

    有时有必要从模拟对象中调用真实方法,在这种情况下,我们需要使用doCallRealMethod(),因为doNothig()是默认行为。

    在以下示例中,即使是模拟对象,也会调用userRepository中的真实方法。

    @Test
    public void testUpdateNameCallRealRepositoryMethod() {
     
       doCallRealMethod().when(mockedUserRepository).updateName(anyLong(), anyString());
      
       userService.updateName(1L,"真实调用方法");
      
       verify(mockedUserRepository, times(1)).add(1L,"真实调用方法");
    }
    

    • 公众号FunTester首发,更多原创文章:FunTester430+原创文章,欢迎关注、交流,禁止第三方擅自转载。

    热文精选

  • 相关阅读:
    docker镜像文件导入与导出,支持批量
    配置和启动Kubernetes服务
    在CentOS 7 上安装docker
    安装CentOS7精简版后的配置工作
    Docker镜像加速
    docker命令不需要敲sudo的方法
    建立时间和保持时间(setup time 和 hold time)
    时序收敛:基本概念
    GitHub: Windows 下的简单使用
    K-means算法和矢量量化
  • 原文地址:https://www.cnblogs.com/FunTester/p/13446602.html
Copyright © 2011-2022 走看看