单元测试总结
Posted zkk502
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单元测试总结相关的知识,希望对你有一定的参考价值。
单元测试
1 为什么要进行单元测试
- 单元测试可以有效地测试某个程序模块的行为,是未来重构代码的信心保证。
- 单元测试的测试用例要覆盖常用的输入组合、边界条件和异常。
- 单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug。
- 单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug。
2 测试框架
Junit+mockito+assertj
3 使用框架
3.1 项目引入相关jar包
a. springboot框架,maven引入spring-boot-starter-test即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
b.springmvc框架maven引入以下依赖:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
3.2 编写测试类骨架
a. 针对要测试的类,在test包下创建对应main的包名,并将class的名称命名为以Test结尾的名称;
例如:要针对com.tasly.share.core.score UserScoreService接口进行单元测试,需要在test包下建立com.tasly.share.core.score UserScoreServiceTest类。
b. 配置该类的测试运行环境
一种方式:直接在类上增加@RunWith(MockitoJUnitRunner.class)
例如:@RunWith(MockitoJUnitRunner.class)
public class UserScoreServiceTest {}
第二种方式:测试类统一继承同一个父类,父类上增加@RunWith(MockitoJUnitRunner.class)注解。
例如: public class UserScoreServiceTest extends AbstractUnitTest {}
@RunWith(MockitoJUnitRunner.class)
public abstract class AbstractUnitTest {}
推荐使用第二种方式。
3.3 测试类中增加测试方法
a. 方法访问级别必须是public 的
b. 返回类型必须是void,
c. 方法名字最好是和要测试的方法名相同或者意义比较贴近。
d. 方法上需要增加@Test注解
例如:
@Test
public void getScoreByUid(){
}
3.4 增加@InjectMocks和@Mock成员变量
a. 需要进行单元测试的类需要通过@InjectMocks 注入;
方式有2中:
其一: 注入接口 new出接口的子类
例如:
@InjectMocks
private UserScoreService userScoreService = new UserScoreServiceImpl();
其二: 直接注入子类
例如:
@InjectMocks
private UserScoreServiceImpl userScoreService;
b. 测试类需要用到的类 需要通过@Mock注入,包括其他的service,repository等等;
例如:
@Mock
private ShareUserScoreRepository scoreRepository;
@Mock
private UserScoreLogService userScoreLogService;
3.5 静态导入Mockito,Matchers,Assertions类,简化使用
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
3.6 实现测试用例方法
根据业务场景自行编写测试代码;
例如:
@Test
public void getScoreByUid(){
when(scoreRepository.selectByPrimaryKey(anyInt())).thenReturn(MockFactory.gennerate(ShareUserScore.class));
ShareUserScore scoreByUid = userScoreService.getScoreByUid(1);
assertThat(scoreByUid).isNotNull();
}
MockFactory工厂方法见附录。
3.7 期望值进行断言
可以使用assertThat ,verify 进行返回值的断言。
其他方法自行查阅相关文档。
3.8 针对跑出的异常可以通过全局设置
@Test(expected = RuntimeException.class)
附录
@UtilityClass
public class MockFactory {
public <T> List<T> gennerate(Class<T> tClass, int size) {
return gennerate(gennerate(tClass), size);
}
public <T> List<T> gennerate(T t, int size) {
return Stream.iterate(t, identity())
.limit(size)
.collect(Collectors.toList());
}
public <T> T gennerate(Class<T> tClass) {
PodamFactory factory = new PodamFactoryImpl();
return factory.manufacturePojo(tClass);
}
}
参考文档
https://github.com/hehonghui/mockito-doc-zh#0
集成测试
1 为什么要进行集成测试
1.1集成测试,也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。
1.2实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。一些局部反映不出来的问题,在全局上很可能暴露出来。
2 测试框架
Junit+mockmvc
3 使用框架
3.1 项目引入相关jar包
如上单元测试
3.2 编写测试类骨架
a. IDEA提供了快速创建测试类的方法:把光标放到在类名处,然后按alt+enter>create test就可以创建一个测试类
b. 配置该类的测试运行环境
测试类统一继承同一个父类,父类上增加
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
同时在父类引入 MockMvc
父类例如:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class AbstractIntegrationTest1 {
@Autowired
protected MockMvc mockMvc;
}
子类例如:
public class ProductRestTest extends AbstractIntegrationTest1 {
@Test
public void getProductListInfo() throws Exception {
RequestBuilder requestBuilder;
requestBuilder = get("/mini/productList");
mockMvc.perform(requestBuilder)
.andExpect(status().isOk())
.andExpect(content().string(not("")))
.andExpect(jsonPath("$.resCode").value("0"))
.andDo(print());
}
3.3 使用说明
导入例如 get post put
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
mockMVC的用法
1、mockMvc.perform执行一个请求;
2、MockMvcRequestBuilders.post(“http://127.0.0.1:8888/login“)构造一个请求
3、ResultActions.andExpect添加执行完成后的断言
4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
5、ResultActions.andReturn表示执行完成后返回相应的结果。
Hamcrest
JUnit4.4引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活
例如上例中的not
.andExpect(content().string(not("")))
import static org.hamcrest.Matchers.not;
以上是关于单元测试总结的主要内容,如果未能解决你的问题,请参考以下文章