Mockito使用-----常用demo

目录

 

为什么需要使用mockito

mockito介绍

mockito使用demo

1.springboot使用mockito

2.mockito常用测试demo(官网链接)


为什么需要使用mockito

在实际项目中,当在编写单元测试时,往往遇到需要测试的类有许多依赖,而所依赖的类/对象/资源又有许多依赖,形成了一个非常复杂的依赖树。这时候就需要通过mock的方式虚拟化测试类的依赖,只测试测试类的功能。

mock依赖类1和依赖类2

mockito介绍

Mockito是用于写Java的单元测试框架,在单元测试中使用Mockito来创建和模拟(Mock)假的Java对象,进而简化外部的依赖。

mockito使用demo

1.springboot使用mockito

实体类:

package com.yantaibai.com.mockito.modal;

import lombok.Data;

@Data
public class User {
    private String id;
    private String name;
    private int age;
}

Dao类:

package com.yantaibai.com.mockito.dao;

import com.yantaibai.com.mockito.modal.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserMapper {
    List<User> getUsers();
}

 被测试类:

package com.yantaibai.com.mockito.service;

import com.yantaibai.com.mockito.dao.UserMapper;
import com.yantaibai.com.mockito.modal.User;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class UserService implements IUserService {
    @Autowired
    UserMapper usermapper;

    public List<User> getUser() {
        return usermapper.getUsers();
    }
}

测试类: 

public class UserMock {
    @InjectMocks
    UserService userService;

    @Mock
    UserMapper mapper;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getUserMock(){
        List<User> userList=new ArrayList();
        User user=new User();
        user.setId("123456789");
        user.setName("aaa");
        user.setAge(18);
        userList.add(user);
        Mockito.when(mapper.getUsers()).thenReturn(userList);
        userService.getUser();
        Assert.assertEquals(userService.getUser(),userList);
    }
}

2.mockito常用测试demo(官网链接

verify:检验某一行为是否发生

//Let's import Mockito statically so that the code looks clearer
 import static org.mockito.Mockito.*;

 //mock creation
 List mockedList = mock(List.class);

 //using mock object
 mockedList.add("one");
 mockedList.clear();

 //verification
 verify(mockedList).add("one");
 verify(mockedList).clear();

when(mock.method()).thenReturn():带返回值方法正向测试

when(mock.method()).thenThrow():带返回值方法异向测试

 //You can mock concrete classes, not just interfaces
 LinkedList mockedList = mock(LinkedList.class);

 //stubbing
 when(mockedList.get(0)).thenReturn("first");
 when(mockedList.get(1)).thenThrow(new RuntimeException());

 //following prints "first"
 System.out.println(mockedList.get(0));

 //following throws runtime exception
 System.out.println(mockedList.get(1));

 //following prints "null" because get(999) was not stubbed
 System.out.println(mockedList.get(999));

 //Although it is possible to verify a stubbed invocation, usually it's just redundant
 //If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed).
 //If your code doesn't care what get(0) returns, then it should not be stubbed.
 verify(mockedList).get(0);

when(mock.method(anyInt)).thenReturn():带参数方法测试(入参为任何int值)

when(mock.method(argthat()).thenReturn():带参数方法测试(入参为一定的正则规则)

//stubbing using built-in anyInt() argument matcher
 when(mockedList.get(anyInt())).thenReturn("element");

 //stubbing using custom matcher (let's say isValid() returns your own matcher implementation):
 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));

verify(mock,time()).method(): 检验方法调用了几次

 //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(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)
 verify(mockedList, never()).add("never happened");

 //verification using atLeast()/atMost()
 verify(mockedList, atMostOnce()).add("once");
 verify(mockedList, atLeastOnce()).add("three times");
 verify(mockedList, atLeast(2)).add("three times");
 verify(mockedList, atMost(5)).add("three times");

doThrow(new RuntimeException()).when(mockedList).clear():检验调用方法时抛出异常 

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

   //following throws RuntimeException:
   mockedList.clear();

verify&InOrder:判断同意方法或者不同方法的调用顺序 

// A. Single mock whose methods must be invoked in a particular order
 List singleMock = mock(List.class);

 //using a single mock
 singleMock.add("was added first");
 singleMock.add("was added second");

 //create an inOrder verifier for a single mock
 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");

 // B. Multiple mocks that must be used in a particular order
 List firstMock = mock(List.class);
 List secondMock = mock(List.class);

 //using mocks
 firstMock.add("was called first");
 secondMock.add("was called second");

 //create inOrder object passing any mocks that need to be verified in order
 InOrder inOrder = inOrder(firstMock, secondMock);

 //following will make sure that firstMock was called before secondMock
 inOrder.verify(firstMock).add("was called first");
 inOrder.verify(secondMock).add("was called second");

 // Oh, and A + B can be mixed together at will

verifyzeroInteractions:检查mock方法调用0次

verifyNoMoreInteractions:检查mock方法除了verify,没有再调用

//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);

 verifyNoMoreInteractions(mockedList);

mock方法多次调用测试 

//第一次返回RuntimeException(),再调用全部返回“foo”
when(mock.someMethod("some arg"))
   .thenThrow(new RuntimeException())
   .thenReturn("foo");

 //First call: throws runtime exception:
 mock.someMethod("some arg");

 //Second call: prints "foo"
 System.out.println(mock.someMethod("some arg"));

 //Any consecutive call: prints "foo" as well (last stubbing wins).
 System.out.println(mock.someMethod("some arg"));




//四次分别返回:“one”,“two”,“three”,“three”
when(mock.someMethod("some arg"))
   .thenReturn("one", "two", "three");




//每次调用都返回 "two"
 when(mock.someMethod("some arg"))
   .thenReturn("one")
 when(mock.someMethod("some arg"))
   .thenReturn("two")

自定义返回格式 

when(mock.someMethod(anyString())).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(mock.someMethod("foo"));

 验证异常场景

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

   //following throws RuntimeException:
   mockedList.clear();

调用耗时测试 


   //passes when someMethod() is called no later than within 100 ms
   //exits immediately when verification is satisfied (e.g. may not wait full 100 ms)
   verify(mock, timeout(100)).someMethod();
   //above is an alias to:
   verify(mock, timeout(100).times(1)).someMethod();

   //passes as soon as someMethod() has been called 2 times under 100 ms
   verify(mock, timeout(100).times(2)).someMethod();

   //equivalent: this also passes as soon as someMethod() has been called 2 times under 100 ms
   verify(mock, timeout(100).atLeast(2)).someMethod();

使用抓取器,抓取参数验证 

ArgumentCaptor<String> paramCaptor=ArgumentCaptor.forClass(String.class);
Mockito.doNothing().when(mapper).getId(paramCaptor.capture());
mapper.getId("aaa");
Assert.assertEquals("aaa",paramCaptor.getValue());

 使用抓取器,抓取打印的日志

public class UserMock {
    @InjectMocks
    UserService userService;

    @Mock
    UserMapper mapper;

    @Mock
    Appender appender;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void logEvent(){
        Mockito.when(appender.getName()).thenReturn("mocked");
        Mockito.when(appender.isStarted()).thenReturn(true);
        ((Logger)LogManager.getRootLogger()).addAppender(appender);

        Mockito.when(userService.getName()).thenThrow(new RuntimeException());
        //创建一个抓取器
        ArgumentCaptor<LogEvent> logCaptor=ArgumentCaptor.forClass(LogEvent.class);
        userService.getName();
        logCaptor.getAllValues().stream().filter(event->event.getMessage().equals("get the name error"))
                .findFirst().orElseThrow(AssertionError::new);
    }
    
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值