每个合格的程序员都会告诉你,在进行业务功能开发过程中,对自己开发的业务功能进行单元测试是一项绝对不能忽视的任务,它是研发提测质量的保障,而研发质量,是一个程序员是否干练的唯二指标,涉及研发人员的风评,是我们必须重视,并持续提升的,可见单元测试的重要性,单元测试也是我们对代码的信心的来源。
单元测试与集成测试的区别?
有人说:“我想到了,单元测试就是优雅的公主,集成测试就是勇敢的骑士!”没错,这个类比非常贴切。单元测试就像是保护公主,关注单个组件(类或方法),确保它在任何状况下都能优雅地完成任务。而集成测试则像勇敢的骑士,在广阔的领域里战斗,确保各个组件能够完美搭配,共同完成更大的任务。
单元测试是指测试单一的组件或模块,确保其功能正确。让我们举个例子。假设我们有一个加法函数 add(int a, int b),我们可以写一个单元测试来验证它:
// 测试加法函数
@Test
public void testAdd() {
assertEquals(5, add(2, 3)); // 考察如果输入2和3会不会得到5
}
而集成测试则是将多个组件组合在一起,确保它们可以正确地协同工作。例如,当用户注册完成后,我们不仅需要验证用户数据是否已经保存到数据库,我们还需要验证是否发送了确认邮件。
Spring的测试注解
那么我们如何进行单元测试呢?Spring特意为我们准备了神奇的@Test
注解。@SpringBootTest
可确保你的Spring应用测试环境全部装备就绪;加上@MockBean
和@Autowired
,可以很好的完成单元测试时系统或模块间的隔离,例如:
@SpringBootTest
@AutoConfigureMockMvc
class PersonControllerTest {
@Autowired
private MockMvc mockMvc;
// 对contoller层进行测试,依赖的servicec对象mock出来
@MockBean
private PersonService personService;
Person person;
@BeforeEach
public void setup() {
person = new Person();
person.setId(1L);
// mock personService.getById方法,当id为1时返回person对象
Mockito.when( personService.getById(1L)).thenReturn(person);
}
@Test
public void testGetPerson() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/person/1")).
andExpect(status().isOk()).andReturn();
Result<Person> result = JSON.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
System.out.println(result);
assertNotNull(result.getData());
}
}
上述代码中,@SpringBootTest
表明这是一个Spring Boot测试,@Autowired
是告诉 Spring 框架注入 RegistrationService
实例, @MockBean
是告诉Spring该mock一个 MailSender
bean用于测试。
Mock对象和Spring Boot中的测试
你可能会问,什么是Mock对象呢?想象一下你的城堡被一群狼攻击,你需要训练你的士兵来对抗他们,但是训练中又不能真的放狼来。与此类同,Mock对象就是这些模拟“狼”的兵偶。在Spring Boot中,我们可以借助MockMvc和Mockito等强大的工具,愉快地进行各类测试。
简单的说,Mock对象是为了复杂系统的模块化测试,单元测试时,只对当前模块功能进行测试,对于依赖的模块对象进行mock,从而完成本模块业务的单元测试。
在Spring Boot中,我们可以使用MockMvc
和Mockito
等工具来创建Mock对象和模拟服务,比如:
在这个例子中,MockMvc模拟了一个全功能的Spring MVC测试环境,我们使用它来发送一个GET请求到应用的首页,并校验响应的状态码和视图名称。
测试覆盖率与持续集成
上面的所有测试是不是已经足够?其实,我们还需要知道我们的测试是否覆盖了所有可能的情况,借助工具如 JaCoCo,我们可以很方便地看到测试覆盖率:
与此同时,我们可以使用Jenkins或者Travis CI来做持续集成,这样一旦代码有变动,它就会自动运行所有测试,确保新的改动不会破坏已有的功能。
这就是Spring单元测试的全部内容,让我们回归到编程的世界,编写健壮的代码,享受在Spring与测试中航行的乐趣。记住,只有通过测试的代码,才是安全的代码。愿你在编程的道路上越走越远,加油!
温馨贴士:编写测试不是浪费时间而是省下来以后可能需要花费的大量时间,你品,你细品。