首页 > 其他分享 >Mockito

Mockito

时间:2023-12-06 14:44:06浏览次数:38  
标签:Mockito class Mock 方法 any mock Before

Mockito

1.简介

Mockito 是一种 Java Mock 框架,主要是用来做 Mock 测试,
它可以模拟任何 Spring 管理的 Bean、模拟方法的返回值、模拟抛出异常等等

用于快速创建和配置mock对象。通过创建外部依赖的 Mock 对象, 然后将此 Mock 对象注入到测试类中,简化有外部依赖的类的测试。

我们注重于方法内的逻辑测试即可

官网:https://site.mockito.org/

2.概念介绍

常用注解

Mockito框架中包含了一些常用的注解,下面是对这些注解的详细解释:

  1. @Mock:用于创建一个Mock对象。这个注解创建的Mock对象不会自动注入到Spring容器中。

  2. @MockBean:用于创建一个Mock对象,并将其添加到Spring容器中。这个注解通常用于Spring Boot的集成测试中。

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

  4. . @Spy:用于创建一个Spy对象。Spy对象是一种特殊的Mock对象,它默认会调用真实的方法。

  5. @Captor:用于创建一个参数捕获器。参数捕获器可以用来捕获方法调用的参数值。

  6. @BeforeEach:标记在方法上,表示该方法应该在每个测试方法之前执行。

  7. @AfterEach:标记在方法上,表示该方法应该在每个测试方法之后执行。

  8. @BeforeAll:标记在方法上,表示该方法应该在所有测试方法之前执行一次。

  9. @AfterAll:标记在方法上,表示该方法应该在所有测试方法之后执行一次。

3.mockito使用

注意事项

需要结合Junit使用(普通的Spring项目)

springboot项目的话,boot-test包默认已经引入mockito相关

前期准备

普通的spring项目,倒入相关jar包,

需要结合junit使用

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

     <!--下面几个非强制。根据实际情况决定是否添加-->
      <!--mockito模拟static方法需要引⼊-->
      <dependency>
          <groupId>org.mockito</groupId>
          <artifactId>mockito-inline</artifactId>
          <scope>test</scope>
      </dependency>
      <!--mockito断言匹配器-->
      <dependency>
          <groupId>org.hamcrest</groupId>
          <artifactId>hamcrest-core</artifactId>
          <scope>test</scope>
      </dependency>
      <!--mockito流式断言,比junit自带的assert更强⼤,更不容易出错-->
      <dependency>
          <groupId>org.assertj</groupId>
          <artifactId>assertj-core</artifactId>
          <scope>test</scope>
      </dependency>

springBoot项目的话就无需这些,starter-test包里自带

结合Spring项目使用

基本使用

/**
 * @author xwp
 * @date 2023/12/5 14:25
 */
@RunWith(MockitoJUnitRunner.class)
public class DeviceFacadeImplTest {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @InjectMocks 
    private DeviceFacadeImpl deviceFacade;
    @Mock
    private IEmMemberDeviceService emMemberDeviceService;
 

    @Before
    public void setUp() throws Exception {
      
    }


    /**
     * 测试--正常流程
     */
    @Test
    public void testOpenAutoStreaming() {
        //构建目标方法的请求参数--com.fzs.server.service.facade.DeviceFacade.openAutoStreaming
        OpenStreamingParam openStreamingParam = new OpenStreamingParam();
        openStreamingParam.setUserId("1");
        openStreamingParam.setStreamType(1);
        openStreamingParam.setInstanceId("1");
        String memberId = "1";


        //制造条件  mock其他服务返回数据
        EmMemberDevice emMemberDevice = new EmMemberDevice();
        emMemberDevice.setDeviceRunningStatus(1);
        emMemberDevice.setStatus(50);
        emMemberDevice.setFrozenStatus(0);
        emMemberDevice.setDeviceId("1");
        emMemberDevice.setPhoneId("1");
        when(emMemberDeviceService.getOne(any())).thenReturn(emMemberDevice);



        //测试调用目标方法
        OpenAutoStreamResult openAutoStreamResult = deviceFacade.openAutoStreaming(memberId, openStreamingParam);
        logger.info("返回结果,{}", openAutoStreamResult);
    }

}

4.常见场景

1.如何mock@Value引入的属性

可以用反射+@Before

@Before:在目标方法执行前会调用(在junit 5.x中,@Before主键被@BeforeEach所替代。)

@Before
  public void setUp() throws Exception {
      //mock设置@Value的值 (反射)
      Field field = DeviceFacadeImpl.class.getDeclaredField("enableADN");
      field.setAccessible(true);
      field.set(deviceFacade, false);
  }

2.返回void的方法mock?

doNothing

doNothing().when(stringValueOperations).set(any(String.class), any(String.class));

3.如何mock redisTemplate的set/get方法

在@Before里面mock valueOperations对象,然后在@Test方法mock调用其set/get

@Mock
RedisTemplate<String, Object> redisTemplate;
@Mock
private ValueOperations<String, Object> valueOperations;

@Before
public void setUp() throws Exception {
	when(redisTemplate.opsForValue()).thenReturn(valueOperations);
}

@test1
public void test1() throws Exception {
	when(valueOperations.get(any())).thenReturn(1);
  doNothing().when(valueOperations).set(any(String.class), any(Object.class), any(long.class), any(TimeUnit.class));
}

4.mybatisPlus在使用Lambda表达式处理查询问题?

如果在mybatisPlus使用了lambda表达式的查询的话,调用mock对象emDevicesStreamsService的getOne方法,例如:

         EmDevicesStreams ds = emDevicesStreamsService.getOne(new QueryWrapper<EmDevicesStreams>().lambda().eq(EmDevicesStreams::getDeviceId, deviceId).orderByDesc(EmDevicesStreams::getId).last(" LIMIT 1 "));

会报错:

can not find lambda cache for this entity [com.fzs.server.service.entity.EmDevicesStreams

这个问题是由于MyBatis Plus在处理Lambda表达式时,需要获取实体类的元数据,但在Mock环境中,由于类加载器的问题,可能无法正确获取这些元数据,从而导致这个错误。

解决:

在@Before里面添加:

 TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), EmDevicesStreams.class);

具体原因分析参考:

https://blog.csdn.net/qq_36491545/article/details/109091325

标签:Mockito,class,Mock,方法,any,mock,Before
From: https://www.cnblogs.com/cutesheep/p/17879508.html

相关文章

  • mockito
     项目中引入 mockito,报错:java.lang.IllegalStateException:Couldnotinitializeplugin:interfaceorg.mockito.plugins.MockMaker(alternate:null)解决:https://howtodoinjava.com//plugin-mockmaker-error/ <!--https://mvnrepository.com/artifact/org.mockito/m......
  • Mockito单元测试最佳实践
    Mockito可以帮助我们模拟创建对象,经常用于模拟外系统、数据库、及其它方法中调用的对象 使用mockito时,单元测试类需要加上注解@RunWith(MockitoJUnitRunner.class),在@Before方法中加上MockitoAnnotations.openMocks(this);使用spring框架时,经常使用@Autowired注解,在这里被注......
  • mockito5.4.0单元测试(14) --捕获mock对象调用某方法时的参数ArgumentCaptor,断言其参
    mockito官方文档地址:https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#resetting_mocks@Testpublicvoidtest_resetting(){//youcanenablepartialmockcapabilitiesselectivelyonmocks:LinkedListmock=mock(Linked......
  • mockito5.4.0单元测试(12) --spy一个真实的对象,使该真实对象可以被mock操作和verify验
    mockito官方文档地址:https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#spy//new一个真实对象Listlist=newLinkedList();Listspy=spy(list);//把这个真实对象放到spy方法里//optionally,youcanstuboutsomemethods:whe......
  • mockito5.4.0单元测试(11) --do when家族的方法们:doReturn()|doThrow()| doAnswer()|
    mockito官方文档地址:https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#do_family_methods_stubs//mock一个对象HashMapmockMap=mock(HashMap.class);  doCallRealMethod方法示例://当mock对象调用put和size方法时,都调用真实的方......
  • mockito5.4.0单元测试(9) --调用同一个方法和参数依次返回不同的值thenReturn和thenTh
    mockito官方文档地址:https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#exact_verification//mock一个对象ListsingleMock=mock(List.class);when(singleMock.get(20)).thenThrow(newRuntimeException())//mock第一次调用......
  • Mockito 静态类中的void方法
    moke例子(我直接用伪代码)publicclassDictUtils{ publicstaticvoidremoveDictCache(Stringkey){ //执行得方法业务 }}你的业务代码中引用这个类的方法publicvoiddeleteDictTypeByIds(Long[]dictIds){ DictUtils.removeDictCache(Stingkey); //业务代码......
  • mockito5.4.0单元测试(8) --验证某个方法从未被调用
    mockito官方文档地址:https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#30  //usingmocks-onlymockOneisinteractedmockOne.add("one");//ordinaryverificationverify(mockOne).add("one"); //验证调用过addon......
  • mockito5.4.0单元测试(5) --校验mock对象的某种方法的准确调用次数
     mokito官方文档地址:https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#exact_verification//mock一个对象LinkedListmockedList=mock(LinkedList.class);//使用mock对象来操作mockedList.add("once");//添加"once"一次......
  • mockito5.4.0单元测试(4) --主动throw异常,模拟异常处理
    importstaticorg.mockito.Mockito.*;  //引入类  LinkedListmockedList=mock(LinkedList.class);  //获得mock对象 //stubbingwhen(mockedList.get(0)).thenReturn("first");     //如果获取0索引,则返回:first when(mockedList.get(1)).the......