Mock 使用总结(Spring boot)

  项目是spring boot 底座,在进行单元测试的时候,使用到了mock。

参考内容:https://blog.youkuaiyun.com/qq_36688143/article/details/97393949

  测试需求:

    1.单元测试不依赖第三方组件(包括数据库)

    2.单元测试对于第三方自研发接口或者非本组内单元,进行屏蔽

  分析:

     spring boot 一般的单元测试需要运行在容器内,我们会采取如下步骤进行单元测试,示范:

1.依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

2.测试类

package com.xxx.service;

import com.xxxx.domain.LearnResource;

import org.junit.Assert; import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

import static org.hamcrest.CoreMatchers.*;

@RunWith(SpringRunner.class)

@SpringBootTest

public class LearnServiceTest {

@Autowired

private LearnService learnService;

@Test

public void getLearn(){

LearnResource learnResource=learnService.selectByKey(1001L);

Assert.assertThat(learnResource.getAuthor(),is("xxxxx")); } }

存在问题:

           使用了容器,在@RunWith上面我们一般会使用自己的运行类,这样子不满足需求,第一点,我们会去初始化数据库,第二点,我们对于第三方注入没有很好的挡板,导致不是我们的测试对象也进行了运行,可能会遇到第三方未知错误。

改善示例:

   解释:1.@RunWith(SpringRunner.class)声明在Spring的环境中进行单元测试,这样Spring的相关注解就会被识别并起效

                2.用@SpringBootTest,它会扫描应用程序的spring配置,并构建完整的Spring Context

               3.通过@SpringBootTest我们可以指定启动类,或者给@SpringBootTest的参数webEnvironment赋值为SpringBootTest.WebEnvironment.RANDOM_PORT,这样就会启动web容器,并监听一个随机的端口,同时,为我们自动装配一个TestRestTemplate类型的bean来辅助我们发送测试请求

   优化:1.不使用@Autowired

               2.不启动容器

               3.脱离数据库

     

@RunWith(MockitoJUnitRunner.class)

@Sld4j

public  class  test{

@InjectMocks

private   xxxxx   xxxx;-----目标对象(只能是实现,不能是接口)

@Mock

private xxxxx   xxxx;  ----非本测试对象,但是需要依赖的内容

@Test

public void Test(){

//TODO  这里写测试逻辑

}

}

解释一下:

a.@Mock 下面注入的内容,如果没有返回值需要接收,或者测试对象不需要返回值继续后续的逻辑,那我们已经把第三发的内容屏蔽了,你不用关心了。

b.@Mock 下面注入的内容,测试对象需要其返回值,返回值影响后续的操作,那我们一般这样做。

Mockito.when(Mock下面的内容).thenReturn(xxx);    xxx------指的是特定的测试需要的对象和属性值。也就是在你运行的时候需要的内容,然后辅助你的案例继续往后运行。

可能遇到的问题:

1.SpringContextUtil获取bean报错空指针,也就是说这个你没处理好,可以参照这个处理:

@Mock

ApplicationContext  appliactionContext;

@Test

public void Test(){

new SpringContextUtil.setAppliactionContext(appliactionContext);//这样我们就把mock对象给到了这个类型里面。

}

2.方法中存在@Value 这样的写法,主要是注入了配置文件的值,那么我们这样去做

ReflectionTestUtils.setField(测试对象,"@Value下面的key",指定你需要的value);

这样写法,我们就可以给到指定的值了。

3.上下文为空

提供一个思路,看上下文的写法。一般是提供一个instance,之后再进行instance相关操作。

@Mock

ServiceContext   serviceContext;---------先mock你的上下文,理解成一个对象

ReflectionTestUtils.setField(new ServiceContext(),"instance",serviceContext);-----这样就把对象给了我们的上下文。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值