Java测试框架系列:Mockito 详解:第一部分:对象创建

Mockito 详解:第一部分:对象创建

零:前提条件

先明确一个词:存根(或者说是打桩),指的是对某个方法指定返回策略的操作(具体表现为两种:1指定返回值,2使用doCallRealMethod()或者thenCallRealMethod()指定当方法被调用时执行实际代码逻辑),功能就是当测试执行到此方法时直接返回我们指定的返回值(此时不会执行此方法的实际代码逻辑)或者执行此方法的实际代码逻辑并返回。比如:

我们先定义一个对象:

public class Mock {

    public String m1() {
        throw new RuntimeException();
    }
}

然后我们进行下面的操作:

Mock m = Mockito.mock(Mock.class);

//对m1()方法进行存根
Mockito.doReturn("1").when(m).m1();

基于上面的代码我们可以说:我们对m对象的m1()方法进行了存根

此时我们调用m对象的m1()方法时,可以直接得到返回值"1"而不会执行m1方法的实际代码逻辑:

Assert.assertEquals("1",m.m1());

此时断言为真。


下文示例代码会使用到的对象:

public class Foo {

    private Bar bar;

    public int sum(int a, int b) {
        return bar.add(a, b);
    }
}

public class Bar {

    public int add(int a, int b) {
        return a + b;
    }
}

测试中我们创建的对象一般可以分为三种:被测对象mock对象spy对象

首先我们明确一下这三种对象的概念:

  1. 被测对象:即我们想要测试的对象,比如xxService、xxUtils等。
  2. mock对象:一般为我们被测对象的依赖对象。典型如被测对象的成员变量。主要是一些测试中我们不关注的对象。我们只想要得到这些对象的方法的返回值。而不关注这些方法的具体执行逻辑。此时我们可以将这些对象创建为mock对象。
  3. spy对象:在Mockito中它是基于部分mock概念提出的。spy对象也可由mock对象使用特定参数下创建。也就是说:**spy对象其实是一种特殊的mock对象。**和mock对象一样,它可以作为被测对象的依赖对象。此时它和mock对象的最大的区别是mock对象的方法如果没有被存根,调用时会返回相应对象的空值(下文有详细介绍);而spy对象的方法被调用时则会调用真实的代码逻辑。

在基于JUnit测试框架的测试代码书写时,我们有两种方式可以激活Mockito框架对其相关注解(@InjectMocks/@Mock/@Spy)的支持。

  1. 使用@RunWith(MockitoJUnitRunner.class),如下所示

    1. public class Foo {
      
          private Bar bar;
      
          public int sum(int a, int b) {
              return bar.add(a, b);
          }
      }
      
      public class Bar {
      
          public int add(int a, int b) {
              return a + b;
          }
      }
      
      @RunWith(MockitoJUnitRunner.class)
      public class MockitoTests {
      
          @InjectMocks
          private Foo foo;
      
          @Mock
          private Bar bar;
      
          @Test
          public void mockTest() {
              Mockito.when(bar.add(1, 2)).thenReturn(7);
              int result = foo.sum(1, 2);
              Assert.assertEquals(7, result);
          }
      }
      
  2. 使用MockitoAnnotations.openMocks(this),如下所示:

    1. public class MockitoTests {
      
          @InjectMocks
          private Foo foo;
      
          @Mock
          private Bar bar;
      
          @Before
          public void beforeClass() {
              MockitoAnnotations.openMocks(this);
          }
      
          @Test
          public void mockTest() {
              Mockito.when(bar.add(1, 2)).thenReturn(7);
              int result = foo.sum(1, 2);
              Assert.assertEquals(7, result);
          }
      }
      

下文中若使用注解方式定义mock对象不再重复说明,优先选择使用@RunWith(MockitoJUnitRunner.class)的方式。

一:创建被测试对象

1:创建被测对象

使用@InjectMocks注解

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    @InjectMocks
    private Foo foo;
  	
    @Test
    public void mockTest() {
      	...
    }
}

@InjectMocks的作用:标记应执行注入的字段(指此对象内的字段应该被自动的注入,注入的值来自@Mock或@Spy注解的字段)。

  • 允许快速的mock和spy注入。
  • 最大限度地减少重复的mock和spy注入代码。

@InjectMock成员变量的自动注入示例:

  • 组合@Mock注解使用:

  • @RunWith(MockitoJUnitRunner.class)
    public class MockitoTest {
    
        //foo 对象内部的成员变量会自动被 @Mock 注解的生成的对象注入。
        @InjectMocks
        private Foo foo;
    
        //bar 对象会自动的注入到 @InjectMocks 注解的对象的成员变量中去。
        @Mock
        private Bar bar;
    
        @Test
        public void mockTest() {
            //先对mock对象的待测方法进行存根
            Mockito.when(bar.add(1, 2)).thenReturn(7);
    
            int result = foo.sum(1, 2);
            //验证是否是存根返回的值
            Assert.assertEqua
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值