mockito使用说明

mockito使用教程

mockito主要是为了解决在junit测试过程中,对部分方法进行mock,类似于对方法的实现做了一些“挡板”。当对方法进行调用时,可以实现对待测试方法的各种注入,模拟等

1. 如何添加到项目

  • maven引入

在pom中加入以下内容,版本号随最新mockito版本

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>3.2.4</version>
</dependency>

2. 用法部分总结

2.1 通过mock()方法构造出对象,并使用verify()方法校验对象的方法是否已经被调用

例:

    public void testListMockito() {
        List mockedList = mock(List.class);

        // 对lict做 add() clear() 操作
        mockedList.add("one");
        mockedList.clear();

        // 对对lict的 add() clear() 操作进行校验,应通过
        verify(mockedList).add("one");
        verify(mockedList).clear();

        // 对list的 get方法做校验,应无法通过
        verify(mockedList).get(0);
    }

2.2 对mock()构造的对象,方法调用的结果进行替换,当该方法被调用时,就会返回固定结果

例:

    @Test
    public void testStubMockito() {
        LinkedList mockedList = mock(LinkedList.class);

        // 将 mockedList.get(0)方法的调用结果替换为 "first"
        when(mockedList.get(0)).thenReturn("first");

        // 返回 "first"
        System.out.println(mockedList.get(0));

        // 返回 null
        System.out.println(mockedList.get(999));

        // 返回 "first"
        System.out.println(mockedList.get(0));
    }

2.3 mockito可以构建出任意参数传入待测试的方法中进行Stub,类似参数匹配,当下一次调用时,就会返回固定的结果

    LinkedList mockedList = mock(LinkedList.class);

    //当调用 mockedList get()方法时,固定返回element
    when(mockedList.get(anyInt())).thenReturn("element");

    //自定义参数值,只有当传入的参数满足条件时,才会在调用contains()方法时返回固定 true
    when(mockedList.contains(argThat(isValid()))).thenReturn(true);

    //following prints "element"
    System.out.println(mockedList.get(999));

    //you can also verify using an argument matcher
    verify(mockedList).get(anyInt());

    //argument matchers can also be written as Java 8 Lambdas
    verify(mockedList).add(argThat(someString -> someString.length() > 5));

2.3 校验方法调用次数

可以判断某个方法在传入某一类参数调用时,调用的次数。

  • times(1) 被调用了一次
  • never() 从未被调用
  • atMost(1) 最多被调用一次
  • atLeastOnce() 最少被调用一次
  • atLeast(2) 最少被调用2次
    //using mock
    mockedList.add("once");
    verify(mockedList).add("once");
    verify(mockedList, times(1)).add("once");

2.4 当调用方法时,绑定跑出异常

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

   //将抛出异常 RuntimeException:
   mockedList.clear();

2.5 校验方法调用顺序

  • 校验一个对象的方法被调用的顺序,使用inOrder()方法
    List singleMock = mock(List.class);

    //两次调用add()方法
    singleMock.add("was added first");
    singleMock.add("was added second");

    InOrder inOrder = inOrder(singleMock);

    //following will make sure that add is first called with "was added first", then with "was added second"
    inOrder.verify(singleMock).add("was added first");
    inOrder.verify(singleMock).add("was added second");
  • 对于多个mock对象的方法执行顺序,也可以使用inOrder()
    List firstMock = mock(List.class);
    List secondMock = mock(List.class);

    firstMock.add("was called first");
    secondMock.add("was called second");
    firstMock.add("was called third");

    InOrder inOrder = inOrder(firstMock, secondMock);

    inOrder.verify(firstMock).add("was called first");
    inOrder.verify(secondMock).add("was called second");
    inOrder.verify(firstMock).add("was called third");

2.6 使用verifyZeroInteractions()方法保证mock对象未被调用过

例如:

    List mockOne = mock(List.class);
    List mockTwo = mock(List.class);
    List mockThree = mock(List.class);

    mockOne.add("one");

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

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

    // mockTwo mockThree 未被使用过
    verifyZeroInteractions(mockTwo, mockThree);

当需要判断一个mock对象是否被用过,可以是否verifyNoMoreInteractions()

2.7 使用@Mock注解创建mock对象

  • 减少重复mock对象创建代码
  • 增加可读性
public class ArticleManagerTest {
    @Mock
    private LinkedList<String> mockList;

    @BeforeClass
    public void init() {
        // 这块代码必须加上,否则无法初始化,也可以使用MockitoJUnitRunner 或 MockitoRule
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testListMockito() {
        mockList.add("one");
        verify(mockList).add("one");
    }
}

2.8 连续方法调用(类似于迭代方式)

先构建完成mock对象,当有连续几次对该对象的方法进行调用时,会根据每次的调用次序依次返回相应的结果。而后面所有的返回值都跟最后一次的一样,例如:

    when(mockList.get(0))
        .thenThrow(new RuntimeException())
        .thenReturn("foo");
    // 抛出异常
    mockList.get(0);

    // 返回 "foo"
    System.out.println(mockList.get(0));
    // 依然返回 "foo"
    System.out.println(mockList.get(0));

注意:如果有多个 when-thenReturn 则后一个会将前一个覆盖

2.8 自定义一些注入返回方法

使用thenAnswer()方法,同时再根据Answer接口,实现自定义内容。

    when(mockList.get(0)).thenAnswer(
            new Answer() {
                public Object answer(InvocationOnMock invocation) {
                    Object[] args = invocation.getArguments();
                    Object mock = invocation.getMock();
                    return "called with arguments: " + Arrays.toString(args);
                }
            });

    //Following prints "called with arguments: [foo]"
    System.out.println(mockList.get(0));

2.9 当待mock替换的方法的参数为空时,需要使用其他方式进行stub

主要使用doReturn()|doThrow()| doAnswer()|doNothing()|doCallRealMethod()等方法。

使用方法如下:

doThrow(new RuntimeException()).when(mockedList).clear();
// 抛出异常
mockedList.clear();

2.10 使用spy()创建真实对象进行mock,区别在于会真实执行相应对象的方法


   List list = new LinkedList();
   List spy = spy(list);

   //可以对方法进行stub
   when(spy.size()).thenReturn(100);

   //调用真实方法
   spy.add("one");
   spy.add("two");

   //prints "one"
   System.out.println(spy.get(0));

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

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

在使用spy()方法时,需要注意doReturn|Answer|Throw()等方法进行stub

   List list = new LinkedList();
   List spy = spy(list);

   //因为调用的是真实方法,会导致空指针。
   when(spy.get(0)).thenReturn("foo");

   //正确方式
   doReturn("foo").when(spy).get(0);

2.11 修改unstubbed调用的默认值

相当于将一个类中的

    Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
    Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个非常流行的Java框架,Mockito和PowerMock是两个常用的Java测试框架。集成Mockito和PowerMock可以帮助我们更好地进行单元测试和集成测试。下面是Spring Boot集成Mockito和PowerMock的步骤: ### 1. 添加依赖 在pom.xml中添加以下依赖: ``` <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.10.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> ``` ### 2. 编写测试类 编写需要测试的类和测试类,例如: ``` @Service public class UserService { @Autowired private UserRepository userRepository; public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } } @RunWith(PowerMockRunner.class) @PrepareForTest(UserRepository.class) public class UserServiceTest { @InjectMocks private UserService userService; @Mock private UserRepository userRepository; @Test public void testGetUserById() { Long id = 1L; User user = new User(); user.setId(id); user.setName("MockitoTest"); Mockito.when(userRepository.findById(id)).thenReturn(Optional.of(user)); User result = userService.getUserById(id); Assert.assertEquals(result.getName(), "MockitoTest"); } } ``` ### 3. 运行测试 运行测试类,如果测试通过,则说明Mockito和PowerMock已经成功集成到Spring Boot中。 以上是Spring Boot集成Mockito和PowerMock的基本步骤。需要注意的是,Mockito和PowerMock虽然可以帮助我们进行更好的测试,但是过度使用也会导致测试变得复杂和难以维护,因此需要谨慎使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值