mockito使用

mockito学习资料:

http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html

http://blog.csdn.net/sdyy321/article/details/38757135

?

1、验证行为是否发生


1

2

3

4

5

6

7

8

@Test

public void mockedList(){

    List mockedList = mock(List.class);

    mockedList.add("one");

    mockedList.clear();

    verify(mockedList).add("one");

    verify(mockedList).clear();

}

验证add和clear是否执行。

2、验证返回值


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

@Test

    public void two(){

        //模拟创建一个List对象

        LinkedList mockLinkedList = mock(LinkedList.class);

        //打桩,当LinkedList调用get(0)方法时,第一次返回zero,第二次n次返回nnnn

        when(mockLinkedList.get(0)).thenReturn("zero").thenReturn("nnnn");

        //使用mock对象

        System.out.println(mockLinkedList.get(0));

        System.out.println(mockLinkedList.get(0));

        System.out.println(mockLinkedList.get(0));

        //验证行为get是否发生

        verify(mockLinkedList).get(0);

    }

这里注意所有的方法都会有返回值,如果没有设置返回值,那么就会返回null或者空集、适当的类型。 Stubbing可以被重写,也就是同一个参数方法可以放回不同的值,但是已最后一次设置的值为标准。一旦被 Stubbed,无论方法被调用多少次,都只会返回Stubbed value。最后一次最重要原则。

3、参数匹配

通过equals()来验证参数。

不同的参数返回不同的结果:


1

2

when(comparable.compareTo("Test")).thenReturn(1); 

when(comparable.compareTo("Omg")).thenReturn(2);

一旦你使用了参数匹配器,那么所有的参数都必须由匹配器给出:


1

2

3

4

5

6

7

8

9

10

11

//stubbing using built-in anyInt() argument matcher

 when(mockedList.get(anyInt())).thenReturn("element");

 //stubbing using hamcrest (let‘s say isValid() returns your own hamcrest matcher):

 when(mockedList.contains(argThat(isValid()))).thenReturn("element");

 //following prints "element"

 System.out.println(mockedList.get(999));

 //you can also verify using an argument matcher

 verify(mockedList).get(anyInt());


1

2

3

4

5

verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));

   //above is correct - eq() is also an argument matcher

   verify(mock).someMethod(anyInt(), anyString(), "third argument");

   //above is incorrect - exception will be thrown because third argument is given without an argument matcher.

4、验证调用次数


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

@Test

    public void three(){

        List mockedList = mock(List.class);

        mockedList.add(1);

        mockedList.add(2);

        mockedList.add(2);

        mockedList.add(3);

        mockedList.add(3);

        mockedList.add(3);

        //验证是否被调用一次,等效于下面的times(1),默认的,可以不写

        verify(mockedList).add(1);

        verify(mockedList,times(1)).add(1);

        //验证是否被调用2次 

        verify(mockedList,times(2)).add(2);

        //验证是否被调用3次 

        verify(mockedList,times(3)).add(3);

        //验证是否从未被调用过

        verify(mockedList,never()).add(4);

        //验证至少调用一次

        verify(mockedList,atLeastOnce()).add(1);

        //验证至少调用2次

        verify(mockedList,atLeast(2)).add(2);

        //验证至多调用3次

        verify(mockedList,atMost(3)).add(3);

    }

add(1)这个方法被调用了1次,add(2)这个被调用了2次。add(3)这个方法被调用了3次,如果将verify(mockedList,times(1)).add(3);运行后那么就会出现错误:

5、模拟方法体抛出异常


1

2

3

4

5

6

doThrow(new RuntimeException()).when(mockedList).clear(); 

  //following throws RuntimeException:

mockedList.clear();

doThrow(new RuntimeException()).when(list).add(1); 

list.add(1);

6、验证执行的顺序


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Test

    public void four(){

        List firstList = mock(List.class);

        List secondList = mock(List.class);

        //using mocks

        firstList.add("was called first one mock");

        secondList.add("was called second one mock");

        //create inOrder object passing any mocks that need to be verified in order

        InOrder indOrder = inOrder(firstList,secondList);

        indOrder.verify(firstList).add("was called first one mock");

        indOrder.verify(secondList).add("was called second one mock");

    }

如果将11,12调换,

indOrder.verify(secondList).add("was called second one mock");

indOrder.verify(firstList).add("was called first one mock");

会出现如下错误:

可是如果顺序如下:


1

2

3

4

5

firstList.add("was called first one mock");

secondList.add("was called second one mock");

InOrder indOrder = inOrder(secondList,firstList);

indOrder.verify(firstList).add("was called first one mock");

indOrder.verify(secondList).add("was called second one mock");

inorder中顺序调换后,上面程序居然没有出错?难道我理解错了。验证的顺序是按照inOrder中给出的,也就是second要在first前面,而在verify中明显second在first后验证了,应该出错啊。

7、模拟对象上没有相互关系


1

2

3

4

5

6

7

8

9

10

11

//using mocks - only mockOne is interacted

 mockOne.add("one");

 //ordinary verification

 verify(mockOne).add("one");

 //verify that method was never called on a mock

 verify(mockOne, never()).add("two");

 //verify that other mocks were not interacted

 verifyZeroInteractions(mockTwo, mockThree);

8、找出多余的调用


1

2

3

4

5

6

7

8

9

10

11

12

//using mocks

 mockedList.add("one");

 mockedList.add("two");

 verify(mockedList).add("one");

 //following verification will fail 检查是否有未被验证的行为

 verifyNoMoreInteractions(mockedList);

  verify(list,times(2)).add(anyInt()); 

//检查是否有未被验证的互动行为,因为add(1)和add(2)都会被上面的anyInt()验证到,所以下面的代码会通过 

   verifyNoMoreInteractions(list);

mockedList还有add("two")没有验证,所以出错。

9、使用注解来mock

这里注意要在构造函数中初试化mock对象,否则mock对象为null。

也可以通过在类上使用注解:@RunWith(MockitoJUnitRunner.class)

这样就不需要初始化mock了。

10、连续调用


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Test(expected = RuntimeException.class

    public void consecutive_calls(){ 

        List mockList = mock(List.class);

        //模拟连续调用返回期望值,如果分开,则只有最后一个有效 

        when(mockList.get(0)).thenReturn(0); 

        when(mockList.get(0)).thenReturn(1); 

        when(mockList.get(0)).thenReturn(2); 

        when(mockList.get(1)).thenReturn(0).thenReturn(1).thenThrow(new RuntimeException()); 

        assertEquals(2,mockList.get(0)); 

        assertEquals(2,mockList.get(0)); 

        assertEquals(0,mockList.get(1)); 

        assertEquals(1,mockList.get(1)); 

        //第三次或更多调用都会抛出异常 

        mockList.get(1); 

    }

11、使用回调来stub

通用:


1

2

3

4

5

6

7

8

9

10

when(mock.someMethod(anyString())).thenAnswer(new Answer() {

     Object answer(InvocationOnMock invocation) {

         Object[] args = invocation.getArguments();

         Object mock = invocation.getMock();

         return "called with arguments: " + args;

     }

 });

 

 //Following prints "called with arguments: foo"

 System.out.println(mock.someMethod("foo"));

使用:


1

2

3

4

5

6

7

8

9

10

11

12

@Test

    public void six(){

        List mockList = mock(List.class);

        when(mockList.get(anyInt())).thenAnswer(new Answer<Object>() {

            public Object answer(InvocationOnMock invocation) throws Throwable {

                Object[] args = invocation.getArguments();

                return "hi:"+args[0];

            }

        });

        assertEquals("hi:0",mockList.get(0));

        assertEquals("hi:1",mockList.get(1));

    }

12、对于void方法,有系列函数可以用来处理。

doThrow() doAnswer doNothing doReturn。当一个void的方法有异常抛出时可以使用doThrow()。

13、监控真实对象

当使用spy的时候真正的方法将会被调用,而不再是stub的对象了,这个和部分mock的思想是一样的。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@Test

    public void seven(){

        List list = new LinkedList();

        List spy = spy(list);

         

        //optionally, you can stub out some methods:

        when(spy.size()).thenReturn(100);

         

        //using the spy calls real methods

        spy.add("one");

        spy.add("two");

         

        //prints "one" - the first element of a list

        System.out.println(spy.get(0));

         

        //size() method was stubbed - 100 is printed

         System.out.println(spy.size());

         

        //optionally, you can verify

        verify(spy).add("one");

        verify(spy).add("two");

    }

使用spy的时候需要注意一点:有时候是不能使用when语句的


1

2

3

4

5

6

7

8

List list = new LinkedList();

   List spy = spy(list);

   

   //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)

   when(spy.get(0)).thenReturn("foo");

   

   //You have to use doReturn() for stubbing

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

14、设置未stub的调用的默认值

对于没有stub方法的调用,我们一般返回null,或者是默认类型。也可以修改使其返回你指定的值。


1

2

3

4

5

6

7

8

9

10

11

12

13

@Test

    public void eight(){ 

        //mock对象使用Answer来对未预设的调用返回默认期望值 

        List mocklist = mock(List.class,new Answer(){ 

            public Object answer(InvocationOnMock invocation) throws Throwable { 

                return 999

            }

        }); 

        //下面的get(1)没有预设,通常情况下会返回NULL,但是使用了Answer改变了默认期望值 

        assertEquals(999, mocklist.get(1)); 

        //下面的size()没有预设,通常情况下会返回0,但是使用了Answer改变了默认期望值 

        assertEquals(999,mocklist.size()); 

    }

 

时间: 2024-10-06 02:29:57

mockito使用的相关文章

mockito使用心得

前提:pom引用<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version></dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>sprin

Junit mockito 测试Controller层方法有Pageable异常

1.问题 在使用MockMVC+Mockito模拟Service层返回的时候,当我们在Controller层中参数方法调用有Pageable对象的时候,我们会发现,我们没办法生成一个Pageable的对象,会报一个Pageable是一个接口的错误.当我们把所有的参数从Pageable接口变成Pageable的实现类PageRequest的时候,所有的方法参数都换成PageRequest,又会出现一个新的错误,且不说PageRequest不能作为参数用于hibernate的分页查询,另一方面,它没

Junit mockito

Mock测试是单元测试的重要方法之一. 1.相关网址 官网:http://mockito.org/ 项目源码:https://github.com/mockito/mockito api:http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html 2.什么是Mock测试 Mock 测试就是在测试过程中,对于某些不容易构造(如 HttpServletRequest 必须在Servlet 容器中才能构造出来)或者不容易获

powerMock比easyMock和Mockito更强大(转)

powerMock是基于easyMock或Mockito扩展出来的增强版本,所以powerMock分两种类型,如果你习惯于使用easyMock的,那你就下载基于easyMock的powerMock,反之你喜欢用mockito的话就下载另一种PowerMock. powerMock之所以说它更强大是因为它解决了easyMock和Mockito没有解决的问题,就是可以模仿static,private和final的方法.举例如下: public class User{ private User use

JUnit + Mockito 单元测试(二)

JUnit 是单元测试框架.Mockito 与 JUnit 不同,并不是单元测试框架(这方面 JUnit 已经足够好了),它是用于生成模拟对象或者直接点说,就是"假对象"的工具.两者定位不同,所以一般通常的做法就是联合 JUnit + Mockito 来进行测试. 入门 首先是配置 Mock 对象,看看例子怎么写的. [java] view plain copy List mock = mock( List.class ); when( mock.get(0) ).thenReturn

mockito框架

参考自 http://www.cnblogs.com/silence-hust/p/5017233.html http://blog.csdn.net/sdyy321/article/details/38757135 首先创建一个maven工程 在pom文件中,存在如下依赖 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId&g

mock测试框架Mockito

无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访问实际的文件系统或数据库),而TDD经常会碰到协同模块尚未开发的情况,而mock技术正是解决这些问题的灵丹妙药. mock技术的目的和作用是模拟一些在应用中不容易构造或者比较复杂的对象,从而把测试与测试边界以外的对象隔离开. 我们可以自己编写自定义的Mock对象实现mock技术,但是编写自定义的Mo

Mockito简介(转)

Mockito 是目前 java 单测中使用比较流行的 mock 工具.其他还有 EasyMock,JMock,MockCreator,Mockrunner,MockMaker 及 PowerMock. 项目地址:https://code.google.com/p/mockito/ powermock 简介 EasyMock 以及 Mockito 都因为可以极大地简化单元测试的书写过程而被许多人应用在自己的工作中,但是这两种 Mock 工具都不可以实现对静态函数.构造函数.私有函数.Final

Mockito入门使用一例

Mock的使用有很多方式,我们常用的有以下几种,看示例代码 public class TestMock { @Mock A a;//生成一个A的Mock @Spy A a1 = new A();//生成一个A的Spy, Spy或是InjectMocks必需自己初始化对象,Mock可以不用初始化 @Before public void init(){ MockitoAnnotations.initMocks(this);//初使化Mock } @Test public void testGo(){