Mockito模拟器

1概述

       Mickito模拟器是主流的单元测试框架之一,它需要与Junit测试框架一起使用.

2.相关概念

2.1存根类(Stub)

        存根(Stub)类是实现了一个接口或者抽象类的类,可以在测试过程中可以使用该类对象调用该类的方法进行测试.存根类的对象需要手动创建.如:

Private PingAnEnterService pingAnEnterService = new PingAnEnterServiceImpl();

2.2模拟对象 (Mock)

        模拟对象(mock object)是一个接口或者类的虚拟实现.可以使用mock(T.class)方法或使用@Mock注解生成模拟对象.如:

//模拟创建一个List对象

        List mock = mock(List.class);

                   或

         @Mock

         private List<String,Object> list;

    存根和模拟对象都可以传递给其他的对象进行测试。你的一些单元测试可以测这些类的正确性等。利用存根对象或者模拟对象可以保证测试过程中不受到其他的影响

3.对应的注解

3.1 @Mock

         生成一个模拟对象.与方法mock(T  t)作用一样.有个name属性,可以设置对象的别名.

3.2 @InjectMocks

创建一个实例,其余用@Mock(或@Spy)注解创建的mock将被注入到用该实例中.

注意:必须使用@RunWith(MockitoJUnitRunner.class)Mockito.initMocks(this)进行mocks的初始化和注入。如下:

         方式一:

@RunWith(MockitoJUnitRunner.class) 

public class Test{ 

    @InjectMocks  //创建someHandler实例

    private SomeHandler someHandler; 

    @Mock 

    private OneDependency oneDependency; // 此mock将被注入到someHandler 

方式二:

public class Test{ 

@InjectMocks 

//创建someHandler实例. SomeHandler是类

//private SomeHandler someHandler; 

//创建someHandler实例. SomeHandler是接口

private SomeHandler someHandler = new SomeHandlerImpl(); 

@Mock 

private OneDependency oneDependency; // 此mock将被注入到someHandler 

@Before

public void before(){

    MockitoAnnotations.initMocks(this);

         //给模拟对象属性赋值

         when(oneDependency.setOpenId).thenReturn(“mlsama”);

         . . .

}

}

4.Mockito的限制

以下的类型不能进行构造:

终态类(final classes)

匿名类(anonymous classes)

基本数据类型(primitive types)

5.模拟对象的配置

         其实就是对使用@Mock或mock(T  t)创建的模拟对象方法设置返回值(通过set方法完成成员变量赋值).

5.1方式一

         设置返回值:

                   when(mock.method()).thenReturn(value)

       设置返回异常:

              when(mock.method()).thenThrow(new XXXException())

       迭代风格: 第一次调用返回,第二次返回

when(mock.method()).thenReturn("Hello").thenReturn("World") 

       例如:

@Test

    public void mock1(){

        //模拟创建一个List对象

        List mock = mock(List.class);

              //这里也可以: thenReturn (new RuntimeException());

        when(mock.get(1)).thenReturn(1);

        when(mock.get(1)).thenThrow(newRuntimeException());

        System.out.println(mock.get(1));//抛异常

}

需要注意的是: when(T  t),所以里面的方法的返回值不能是void

5.2方式二

         设置返回值:

                   doReturn(value).when(mock) .method()

       设置返回异常:

              doThrow(new XXXException()).when(mock) .method()

 

例如:

@Test

    public void mock1(){

        //模拟创建一个List对象

        List mock =mock(List.class);

        doReturn(1), when(mock) .get(1);

        doThrow(new RuntimeException()).when(mock) .get(1);

       System.out.println(mock.get(1));//抛异常

}

 

注意:以上方式不支持返回值为void的方法.

5.3对void方法进行方法预期设定 

doNothing() 模拟不做任何返回(mock对象void方法的默认返回) 
doNothing().when(mock).remove();
 
doThrow(Throwable)
模拟返回异常 
doThrow(new RuntimeException()).when(mock).remove();
 

6.验证模拟对象的行为

Mockito 跟踪了所有的方法调用和参数的调用情况。verify()可以验证方法的行为。

格式:

       verify(模拟对象).模拟对象的方法( 参数列表 )

查看下面的例子:

@Test

public void testMap() {

     Map mock =Mockito.mock( Map.class );

     Mockito.when(mock.get( "city" ) ).thenReturn( "深圳" );

     // test code

     assertEquals("城市测试", "深圳", mock.get( "city" ) );

    Mockito.verify(mock).get( Matchers.eq( "city" ) );

     Mockito.verify(mock, Mockito.times( 2 ) );

}

7. Spy

@Spy 或者方法 spy() 可以包含一个真实的对象. 每次调用,除非特出指定,否则委托给该真实对象的调用.

@Test

public void testSpy() {

     // Lets mock aLinkedList

     List list = new LinkedList();

     list.add("yes" );

     List spy =Mockito.spy(list);

     //You have to usedoReturn() for stubbing

     assertEquals("yes", spy.get( 0 ) );

     Mockito.doReturn("foo").when(spy).get(0);

     assertEquals("foo", spy.get( 0 ) );

}

猜你喜欢

转载自blog.csdn.net/mlsama/article/details/79990797