每个合格的程序员都会告诉你,在进行业务功能开发过程中,对自己开发的业务功能进行单元测试是一项绝对不能忽视的任务,它是研发提测质量的保障,而研发质量,是一个程序员是否干练的唯二指标,涉及研发人员的风评,是我们必须重视,并持续提升的,可见单元测试的重要性,单元测试也是我们对代码的信心的来源。

单元测试与集成测试的区别?

有人说:“我想到了,单元测试就是优雅的公主,集成测试就是勇敢的骑士!”没错,这个类比非常贴切。单元测试就像是保护公主,关注单个组件(类或方法),确保它在任何状况下都能优雅地完成任务。而集成测试则像勇敢的骑士,在广阔的领域里战斗,确保各个组件能够完美搭配,共同完成更大的任务。

单元测试是指测试单一的组件或模块,确保其功能正确。让我们举个例子。假设我们有一个加法函数 add(int a, int b),我们可以写一个单元测试来验证它:

// 测试加法函数
@Test
public void testAdd() {
    assertEquals(5, add(2, 3)); // 考察如果输入2和3会不会得到5
}

而集成测试则是将多个组件组合在一起,确保它们可以正确地协同工作。例如,当用户注册完成后,我们不仅需要验证用户数据是否已经保存到数据库,我们还需要验证是否发送了确认邮件。

Spring的测试注解

那么我们如何进行单元测试呢?Spring特意为我们准备了神奇的@Test注解。@SpringBootTest可确保你的Spring应用测试环境全部装备就绪;加上@MockBean@Autowired,可以很好的完成单元测试时系统或模块间的隔离,例如:

Spring系列学习八、Spring单元测试-LMLPHP


@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中,我们可以使用MockMvcMockito等工具来创建Mock对象和模拟服务,比如:

Spring系列学习八、Spring单元测试-LMLPHP

在这个例子中,MockMvc模拟了一个全功能的Spring MVC测试环境,我们使用它来发送一个GET请求到应用的首页,并校验响应的状态码和视图名称。

测试覆盖率与持续集成

上面的所有测试是不是已经足够?其实,我们还需要知道我们的测试是否覆盖了所有可能的情况,借助工具如 JaCoCo,我们可以很方便地看到测试覆盖率:

与此同时,我们可以使用Jenkins或者Travis CI来做持续集成,这样一旦代码有变动,它就会自动运行所有测试,确保新的改动不会破坏已有的功能。

这就是Spring单元测试的全部内容,让我们回归到编程的世界,编写健壮的代码,享受在Spring与测试中航行的乐趣。记住,只有通过测试的代码,才是安全的代码。愿你在编程的道路上越走越远,加油!

温馨贴士:编写测试不是浪费时间而是省下来以后可能需要花费的大量时间,你品,你细品。

01-09 11:07