挖掘机技术哪家强

方便纯净的单测-mockito

方便纯净的单测-mockito

一、背景

我们在线下通过junit测试的时候,测试后的函数中如果如果有对第三方服务的调用(例如数据库,或者依赖的thrift、pigeon服务),那情况可能会复杂一点,如果第三方服务不稳定(服务没有、数据没有等),那我们的测试用例可能就无法跑通。所以为了能够更方便的只测我们自己的代码逻辑、屏蔽第三方的依赖,我们可以利用mockito来对外部调用进行mock。

二、mockito

1、什么是mockito

Mockito is a mocking framework for Java. Mockito allows convenient creation of substitutes of real objects for testing purposes. Enjoy clean tests with mock objects, improved TDD experience and beautiful mocking API.

2、怎样利用mockito进行单测

maven引用

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.8.47</version>
    <scope>test</scope>
</dependency>

 

3、简单示例

import static org.mockito.BDDMockito.when;
import static org.mockito.Mockito.mock;
import static org.testng.Assert.assertEquals;
@Test
public void shouldReturnGivenValueUsingBDDSemantics() {
    //mock
    Flower flowerMock = mock(Flower.class);
    when(flowerMock.getNumberOfLeafs()).thenReturn(TEST_NUMBER_OF_LEAFS);
    //run
    int numberOfLeafs = flowerMock.getNumberOfLeafs();
    //then
    assertEquals(numberOfLeafs, TEST_NUMBER_OF_LEAFS);
}

三、mockito用法

1、mock

写法1:A mockobject = mock(A.class);

写法2:@Mock A mockobject;

mock一个对象,这个mock对象所有行为都会被记录, 默认情况下,所有的函数都有返回值。mock函数默认返回的是null,一个空的集合或者一个被对象类型包装的内置类型,例如0、false对应的对象类型为Integer、Boolean.

2、spy

写法1: A a = spy(A.class);

写法2:@Spy A a;

你可以为真实对象创建一个监控(spy)对象。当你使用这个spy对象时真实的对象也会也调用,除非它的函数被stub了。

3、stub

做测试桩

写法1: when(A.someMethod()).thenReturn(“some result”);

when后面可接 thenReturn thenThrow

写法2:doReturn(“some result”).when(A).someMethod();

doReturn doThrow后接when

注意:测试void函数时需要用写法2

4、verify

验证

//using mock
 mockedList.add("once");
 mockedList.add("twice");
 mockedList.add("twice");
 mockedList.add("three times");
 mockedList.add("three times");
 mockedList.add("three times");
 //following two verifications work exactly the same - times(1) is used by default
 // 下面的两个验证函数效果一样,因为verify默认验证的就是times(1)
 verify(mockedList).add("once");
 verify(mockedList, times(1)).add("once");
 //exact number of invocations verification
 // 验证具体的执行次数
 verify(mockedList, times(2)).add("twice");
 verify(mockedList, times(3)).add("three times");
 //verification using never(). never() is an alias to times(0)
 // 使用never()进行验证,never相当于times(0)
 verify(mockedList, never()).add("never happened");
 //verification using atLeast()/atMost()
 // 使用atLeast()/atMost()
 verify(mockedList, atLeastOnce()).add("three times");
 verify(mockedList, atLeast(2)).add("five times");
 verify(mockedList, atMost(5)).add("three times");

5、参数匹配器(matchers)

6、BDD风格

List<Integer> mockedList = mock(List.class);
//given
given(mockedList.get(0)).willReturn(1);
//when
int result = mockedList.get(0);
//then
Assert.assertEquals(result, 2);

 

四、常用场景示例

5、常用场景示例
@RunWith(MockitoJUnitRunner.class)
public class QixiBookServiceTest {
    //对要测试类的依赖类进行mock
    @Mock
    private QixiBookGateway qixiBookGateway;
    @Mock
    private  MdcGateway mdcGateway;
    @Mock
    DpShopViewGateway dpShopViewGateway;
    //测试类(mock类对象会注入到测试类对象中)
    @InjectMocks
    private QixiBookSerivce qixiBookSerivce;
    @Test
    public void getRoundTest() {
        int cityId = 1;
        int platformId = 20;
        //对依赖类的方法进行mock
        //mock  qixiBookGateway.getQixiBookRound
        when(qixiBookGateway.getQixiBookRound(cityId, platformId)).thenReturn(getDpQixiBookRound());
        //mock  dpShopViewGateway.batchGetShopInfo
        when(dpShopViewGateway.batchGetShopInfo(anyList())).thenReturn(getShopMap());
        //执行测试函数
        QixiBookRoundModel round = qixiBookSerivce.getQixiBookRound(cityId, platformId, nullnull);
        //结果验证
        Assert.assertEquals(round, getResultDpQixiBookRound());
        verify(qixiBookGateway).getQixiBookRound(cityId, platformId);
        verify(dpShopViewGateway).batchGetShopInfo(anyList());
    }
    //...
}

 

 

五、结合idea插件junit generator自动生成测试类

1、安装插件junit generator v2.0

2、配置

OutPut Path: ${SOURCEPATH}/../../test/java/${PACKAGE}/${FILENAME}

修改Junit 4模板

ps:如果有内部类会报错,无法生成测试类

六、mokito + powermock + spock

powermock可以mock static方法

 

参考:

1、官方wikihttps://github.com/mockito/mockito/wiki/FAQ

2、wiki的中文翻译https://github.com/hehonghui/mockito-doc-zh

lpz8120903@163.com