这个方法是不是有问题,单元测试跑一跑不就知道了

生活就像点菜,饥饿时菜会点得特别多,但吃一阵就会意识到浪费;如果慢条斯理地盘算怎么点菜,别人已经要吃完了。这就是决策的复杂性。

作为一个做后端开发不过一年的菜鸟来说,我对后端工程师也有一定的见解。后端工程师要有产品设计思维、代码编写能力、问题排查能力、功能自测能力(bugfree了解下,哈哈)

我个人比较看重bugfree。所以比较注重自测,一般是测试驱动开发,先写单元测试,然后设计并实现业务代码。但是多数情况下,不是在写bug就是在解决bug的路上,哈哈,还需要努力。我们公司也对开发有了严格要求,单元测试覆盖率小于60%,TOP10的团队会在大群里公示15天,可怕不。

为什么强调单元测试呢?有没有遇到过这种情况,当你写的方法被别人调用的时候,突然来个尴尬的空指针,会不会被同事追着打,哈哈。所以今天着重聊一聊单元测试

这张图熟悉不?

这张图熟悉不?

其实上面的图我并不熟悉,因为我们使用Junit4,从官网上截取的。但在Java开发单元测试中最常用的Junit无疑了,接下来结合一般后端开发的MVC模式,一层一层的测试下去。

添加maven依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Spring单元测试基本结构

 @RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
class ApplicationTests {
    @Test
    void contextLoads() {
    }
}

开始测试Controller层

测试Controller层不就是调用接口吗?postman不香吗?哈哈,小编最常用的也是postman请求接口,但是也有了解的必要性。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
// 开启Mock自动注入
@AutoConfigureMockMvc
class ApplicationTests {
    @Autowired
    MockMvc mockMvc;
    @Test
    public void test() throws Exception{
        // 测试请求
        System.out.println(mockMvc);
              // perform开启一个MockMvcRequestBuilders请求,包括post和get方法
        MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.get("/select2")
                .contentType(MediaType.APPLICATION_JSON)
                // 设置请求参数
                //.param("","")
           // 返回状态校验
        ).andExpect(MockMvcResultMatchers.status().isOk())
                //详细请求信息打印到控制台
                .andDo(MockMvcResultHandlers.print())
// 返回打印
                .andReturn();
        System.out.println(mvcResult.getResponse().getContentAsString());
    }


    @Test
    public void test2() throws Exception {
        // 测试插入
        ObjectMapper om = new ObjectMapper();
        Book book = new Book();
        book.setId(100L);
        book.setName("三国");
        String s = om.writeValueAsString(book);
        MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.post("/select2")
                .contentType(MediaType.APPLICATION_JSON)
                .content(s)
        ).andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn();
        System.out.println(mvcResult.getResponse().getContentAsString());
    }
}

Service层

  @RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
class ApplicationTests {
      // 进行注入
    @Autowired
    private UserService userService;
    // 匹配
    @Test
    void contextLoads() {
        List<Book> books = userService.testUserMapper2();
        Assert.assertThat(books.size(), Matchers.is(1));
    }
}

测试json(重点了解一下)

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AspectLockApplication.class)
//添加json序列化和反序列化测试
@JsonTest 
public class Test {
    @Autowired
    JacksonTester<Book> jacksonTester;
    @org.junit.Test
    public void test() throws Exception{
        Book book = new Book();
        book.setAge(10);
        book.setHabies(Arrays.asList("码代码"));
        book.setName("wencaixu");
        book.setTime(new Date());
        // 定义在当前包下的json文件
        Assertions.assertThat(jacksonTester.write(book)).isEqualToJson("book.json"); 
        // 判断序列化结果是否所续期的json
        Assertions.assertThat(jacksonTester.write(book)).hasJsonPathStringValue("@.name"); 
        // 判断值
        Assertions.assertThat(jacksonTester.write(book)).extractingJsonPathStringValue("@.name").isEqualTo("码代码"); 
    }
    @org.junit.Test
    public void testDeserialize() throws Exception{
        String content = "{\"id\":1}";
        Assertions.assertThat(jacksonTester.parseObject(content).getName()).isEqualTo("码代码");
    }
}

看完上面的文章,代码很简单,还是需要多看api文档和官方文档,我想大概大家应该都知道如何对代码进行单元测试了吧,更多的文章在看相声也要敲代码(个人公众号)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值