java代码覆盖率sonar扫描篇(包含如何mock RedisTemplate、静态方法、异常方法)

文章讲述了如何使用Mockito进行Spring应用的单元测试,包括模拟静态方法、异常场景以及如何mockRedisTemplate的操作。作者分享了在LoginService测试中的实践经验,涉及Mock静态方法、异常处理和Redis操作的模拟。
摘要由CSDN通过智能技术生成

 项目的结尾都要进行代码覆盖率的编写,其中有一些小经验分享一下。

  主要设计 静态方法的模拟,正常场景的模拟  异常场景的模拟。  下面这个例子小白看了能解决很多问题

引入的依赖在最后

package com.cn.joey;

import com.cn.joey.light.entity.WorkerNode;
import com.cn.joey.light.mapper.WorkerNodeMapper;
import com.cn.joey.light.service.LoginService;
import com.cn.joey.light.utils.TimeUtil;
import lombok.extern.slf4j.Slf4j;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;


import java.io.UnsupportedEncodingException;
import java.util.Date;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;


@Slf4j
class SwordApplicationTests {

    @InjectMocks
    LoginService loginServiceTest;

    @Mock
    WorkerNodeMapper workerNodeMapper;

     @Mock
    RedisTemplate redisTemplate;


    @Before
    public void setup() throws UnsupportedEncodingException{
        loginServiceTest = spy(new LoginService());//这个很重要
        MockitoAnnotations.initMocks(this);//开启mock 并且注入相应资源  有的是openMocks;本次是initMocks
    }


    /**
     * LoginService中的具体实现方法
     */
    @Test
    public void saveLoginMsgTest01(){
       MockedStatic<TimeUtil> time = Mockito.mockStatic(TimeUtil.class);//如果你使用涉及到静态方法的类必须这样写
       try{

           WorkerNode record = new WorkerNode();
           record.setId(1l);
           record.setCreated(new Date());
           //逻辑 如果用任何参数查询,那么会返回查询结果。 模拟查询类
           when(workerNodeMapper.selectByPrimaryKey(any())).thenReturn(record);
//           time.formatDate(record.getCreated(),"yyyy-MM-dd HH:mm:ss");//模拟静态方法


           String isNotNull = loginServiceTest.saveLoginMsg();//**调用的具体方法,上面都是方法中具体逻辑的模拟数据
           Assert.assertNotNull(isNotNull);//数据不为空

       }catch (Exception e){
           e.printStackTrace();
       }finally {
           time.close();//释放静态全局资源,不然会报错
       }
    }

    /**
     * 异常情况模拟
     */
    @Test
    public void saveLoginMsgTest02(){
        MockedStatic<TimeUtil> time = Mockito.mockStatic(TimeUtil.class);//如果你使用涉及到静态方法的类必须这样写
        try{
            WorkerNode record = new WorkerNode();
            record.setId(1l);
            record.setCreated(new Date());
            //这条逻辑异常情况的模拟
            try {
                Mockito.doAnswer(invocation->{throw new Exception();}).when(workerNodeMapper).selectByPrimaryKey(any());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

//            time.formatDate(record.getCreated(),"yyyy-MM-dd HH:mm:ss");//模拟静态方法

            //方法的触发调用,上面的都是方法中场景需要的数据
            String isNotNull = loginServiceTest.saveLoginMsg();//***调用的具体方法,上面都是方法中具体逻辑的模拟数据
            Assert.assertNotNull(isNotNull);//数据不为空

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            time.close();//释放静态全局资源,不然会报错
        }
    }

    /**
     * 如何mock redis中的opsForValue
     */
    @Test
    public void mockRedisTest01(){
        //首先mock RedisTemplate
        RedisTemplate<String,String> mockRedisTemplate = Mockito.mock(RedisTemplate.class);
        //其次mock RedisTemplate 中具体方法的返回对象 这里以edisTemplate.opsForValue()函数返回对象为例子
        ValueOperations<String,String>  redisMockValue = Mockito.mock(ValueOperations.class);
        redisMockValue.set("a","1");//设置mock值
        Mockito.when(redisTemplate.opsForValue()).thenReturn(redisMockValue);
        //**关键一步,将上面@Mock注入的redisTemplate 强行负值为我们自己mock的mockRedisTemplate
        redisTemplate=mockRedisTemplate;
        //获取mock数值
        Mockito.when(redisMockValue.get(any())).thenReturn("redisMockValue");
    }


}

mockito的依赖

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.6.28</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>3.6.28</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>3.4.0</version>
            <scope>test</scope>
        </dependency>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值