• Mock单元测试


      单元测试的思路是在不涉及依赖的情况下测试代码,一般是测试service层的方法,但实际的代码常会涉及到依赖,一个可行的方法就是使用模拟对象来替换依赖对象。

    1.使用Mockito生成mock对象

      Mockito 是一个流行 mock 框架,可以和JUnit结合起来使用。Mockito 允许你创建和配置 mock 对象。使用Mockito可以明显的简化对外部依赖的测试类的开发。

    一般使用 Mockito 需要执行下面三步

    • 模拟并替换测试代码中外部依赖。

    • 执行测试代码

    • 验证测试代码是否被正确的执行

     1.1.在maven中添加mockito依赖

            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-all</artifactId>
                <scope>test</scope>
            </dependency>

    1.2.静态引用

    如果在代码中静态引用了org.mockito.Mockito.*;,那你你就可以直接调用静态方法和静态变量而不用创建对象,譬如直接调用 mock() 方法。

    1.3.使用 Mockito 创建和配置 mock 对象

    Mockito 还支持通过 @Mock 注解的方式来创建 mock 对象

    使用注解,那么必须要实例化 mock 对象。Mockito 在遇到使用注解的字段的时候,会调用 MockitoAnnotations.initMocks(this) 来初始化该 mock 对象。另外也可以通过使用@RunWith(MockitoJUnitRunner.class)来达到相同的效果。

    注解

    • @Mock:创建 mock 对象
    • @InjectMocks 在 Mockito 中进行依赖注入

    调用方法

    when(…​.).thenReturn(…​.)可以被用来定义当条件满足时函数的返回值,如果你需要定义多个返回值,可以多次定义。当你多次调用函数的时候,Mockito 会根据你定义的先后顺序来返回返回值。Mocks 还可以根据传入参数的不同来定义不同的返回值。譬如说你的函数可以将anyString 或者 anyInt作为输入参数,然后定义其特定的放回值。

    自定义方法的返回值

    Mockito.when(方法).thenReturn(返回值)        

    Mockito.when(方法).thenReturn(返回值1).thenReturn(返回值2)

    无返回值

    对于无返回值的函数,我们可以使用doReturn(…​).when(…​).methodCall来获得类似的效果。例如我们想在调用某些无返回值函数的时候抛出异常,那么可以使用doThrow 方法。

    如下所示:

    Mockito.doThrow(new IOException()).when(mockStream).close()   

    仅调用方法,但啥也不做

    Mockito.doNothing().when(tagRepository).deleteByTagId(1) 

    注:tagRepository有一个方法是 deleteByTagId(int tagId) 

    验证 query 方法是否被 MyDatabase 的 mock 对象调用

    verify(databaseMock).query("* from t");

    查看在传入参数为12的时候方法是否被调用
    verify(test).testing(Matchers.eq(12));

    方法是否被调用两次
    verify(test, times(2)).getUniqueId();

    verify(mock, never()).someMethod("never called");
    verify(mock, atLeastOnce()).someMethod("called at least once");
    verify(mock, atLeast(2)).someMethod("called at least twice");
    verify(mock, times(5)).someMethod("called five times");
    verify(mock, atMost(3)).someMethod("called at most 3 times");

    1.4.mockito的限制

    下面三种数据类型则不能够被测试

    • final classes

    • anonymous classes

    • primitive types

     Mockito 不能够 mock 静态方法,因此我们可以使用 Powermock

    2.powerMock

    powerMock能mock静态、final、私有方法等

    PowerMock支持EasyMock和Mockito。

    2.1PowerMock有两个重要的注解

    @RunWith(PowerMockRunner.class)
    @PrepareForTest( { YourClassWithEgStaticMethod.class })
      如果测试用例里没有使用注解@PrepareForTest,那么可以不用加注解@RunWith(PowerMockRunner.class),反之亦然。当你需要使用PowerMock强大功能(Mock静态、final、私有方法等)的时候,就需要加注解@PrepareForTest。

     2.2基本用法

    详见 http://blog.csdn.net/knighttools/article/details/44630975

    2.2.1和普通Mock的用法相同

    PowerMockito.when(file.exists()).thenReturn(true);

    2.2.2 Mock方法内部new出来的对象

    File file = PowerMockito.mock(File.class);
    ClassUnderTest underTest = new ClassUnderTest();
    PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file);
    PowerMockito.when(file.exists()).thenReturn(true);

    2.2.3 Mock普通对象的final方法

    ClassDependency depencency = PowerMockito.mock(ClassDependency.class);
    ClassUnderTest underTest = new ClassUnderTest();
    PowerMockito.when(depencency.isAlive()).thenReturn(true);

    2.2.4.Mock普通类的静态方法

    PowerMockito.mockStatic(ClassDependency.class);
    PowerMockito.when(ClassDependency.isExist()).thenReturn(true);

    2.2.5 Mock 私有方法

    ClassUnderTest underTest = PowerMockito.mock(ClassUnderTest.class);
    PowerMockito.when(underTest.callPrivateMethod()).thenCallRealMethod();
    PowerMockito.when(underTest, "isExist").thenReturn(true);

    2.2.6. Mock系统类的静态和final方法

    ClassUnderTest underTest = new ClassUnderTest();
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getProperty("aaa")).thenReturn("bbb");

    2.2.7 验证方法

    (1) 验证静态方法:
    PowerMockito.verifyStatic();
    Static.firstStaticMethod(param);
    (2) 扩展验证:
    PowerMockito.verifyStatic(Mockito.times(2)); // 被调用2次

    Static.thirdStaticMethod(Mockito.anyInt()); // 以任何整数值被调用

  • 相关阅读:
    2333
    STL string
    后缀自动机的应用
    省选一轮
    等价类计数问题(Polya定理和burnside引理)
    Prufer序列与树的计数(坑)
    分治算法
    生成函数
    莫队算法
    Xamarin 技术解析
  • 原文地址:https://www.cnblogs.com/zhu-tingting/p/7359756.html
Copyright © 2020-2023  润新知