51Testing软件测试论坛
标题:
单元测试覆盖率如何达到80%以上(下)
[打印本页]
作者:
lsekfe
时间:
2023-3-31 10:45
标题:
单元测试覆盖率如何达到80%以上(下)
常用的 Mockito 方法
Mockito的使用,一般有以下几种组合:参考链接
·
do/when:包括doThrow(…).when(…)/doReturn(…).when(…)/doAnswer(…).when(…)
·
given/will:包括given(…).willReturn(…)/given(…).willAnswer(…)
·
when/then: 包括when(…).thenReturn(…)/when(…).thenAnswer(…)/when(…).thenThrow(…)
Mockito 的多种匹配函数,部分如下:
四:常见问题
1.我自己明明已经模拟了方法,为什么还无法走通?
mock中模拟Mockito.when( 对象.方法名() ).thenReturn( 自定义结果 ),方法名()中参数有的人会使用实际的参数,这样会导致模拟是无法找到正确的结果。所以我们需要使用Mockito.any()去替代,让mock自己去模拟。以及thenReturn中返回的值要符合业务逻辑才能保证业务能够走通。参考:
Mockito.when(deviceFeignService.queryDeviceInfoByDeviceCode(Mockito.any())).thenReturn(deviceExtDataEntity);
2.为什么有时候使用Mockito.any()模拟方法时会报错?
这个是因为有时模拟时的参数类型不正确的原因,参考:Mockito 的多种匹配函数。如果还是报错,建议使用准确值,比如参数为int=1。但就会出现问题一无法返回结果。有知道的大佬可以评论。
3.有时候需要启动参数或者需要连接真实配置(一般junit需要同适用)怎么办?
代表启动参数或者是使用的某个配置文件,注解和代码选择其中之一。参考下图
@ActiveProfiles("baseline")
或者
static {
System.setProperty("env", "baseline");
}
4.有的代码中需要判断常量值才能继续往下走,如何模拟?
说实话,这个问题很恶心,麻烦了很久。后来查到可以使用映射
测试
模拟类,参考:
ReflectionTestUtils.setField()方法接受三个参数:要设置属性值的对象、属性名称和属性值。通过这个方法,我们可以方便地通过反射去设置一个对象的私有变量值,从而在测试代码中控制这个对象的行为。需要注意的是,如果想要通过ReflectionTestUtils.setField()方法修改的变量是静态的,那么第一个参数应为null,因为静态变量属于类级别的而不是实例级别的。
ReflectionTestUtils.setField(deviceServiceImpl, "deviceTypeCodes", "1000");
5. 代码比较老旧,或者有的需要通过连接redis等组件返回结果,业务才能继续往下走?
因为返回的对象无法正常new,我们可以通过Mockito.mock()方法可以创建类或接口的模拟对象。比如:
// redisTemplate写法:
ListOperations<String, String> listOperations = Mockito.mock(ListOperations.class);
Mockito.when(redisTemplate.opsForList()).thenReturn(listOperations);
Mockito.when(listOperations.size(Mockito.any())).thenReturn(10L);
//JDBC写法:
你可以直接带@Before方法中去先初始化模拟:
@Mock
DbUtils openCustomDbUtils;
@Mock
DbUtils newCustomDbUtils;
@InjectMocks
NluDataDao test;
@Before
public void setUp() {
MockitoAnnotations.openMocks(this);
getTestByOne();
}
private void getTestByOne() {
try {
Connection conn = Mockito.mock(Connection.class);
conn.setAutoCommit(true);
PreparedStatement ps = Mockito.mock(PreparedStatement.class);
ResultSet rs = Mockito.mock(ResultSet.class);
ps.setString(1, "1");
int i = ps.executeUpdate();
PowerMockito.when(conn.prepareStatement(Mockito.any())).thenReturn(ps);
PowerMockito.when(ps.getGeneratedKeys()).thenReturn(rs);
PowerMockito.when(ps.executeUpdate()).thenReturn(1);
PowerMockito.when(openCustomDbUtils.getConn()).thenReturn(conn);
} catch (Exception e) {
}
}
@Test
public void testLoadAllAppVOs() {
// Setup
getTestByOne();
getTestByFour();
// Run the test
test.loadAllAppVOs();
}
test.loadAllAppVOs()方法代码:
6. 有得使用了一些框架或者工具类去查询数据,比如mybatiesPlus。代码走不下去怎么办?
其实这也是我为什么讨厌有的人炫技的原因之一。下列报错:
解决方法:
Config config = new Config();
EntityHelper.initEntityNameMap(IotStrategyTriggerSensorDO.class,config);
jar包选择:
import tk.mybatis.mapper.entity.Config;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
五:小技巧
有的工程师写完以后想看一下自己覆盖率的多少,以idea为例有两种方法。(方法2通用)
1.
2.第二种相当于执行mvn test命令。有的时候测试报告和idea扫描的会有不同,需要以自己环境为准。
idea插件:Squaretest,帮助自动生成
单元测试
类。选择第二种使用。
注意:生成后的需要修改,别忘了上面碰到的问题。
欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/)
Powered by Discuz! X3.2