被Spring Boot各种问题坑到哭的经历

在码农界,本人可以算是一个老鸟了,但在Java编程方面,只能算是一个新手,最近折腾Spring Cloud,时常被基于Spring Boot开发中的各种坑绊倒,痛不欲生。

话说昨天就开始研究项目中如何引入自动化测试,于是学习下如何针对Spring Boot项目进行测试代码的编写,最终目的是为了实现测试的自动化。原以为一两个小时就搞定,哪知道今天这个时候(看表,还有2小时下班),才成功将一个Test方法运行起来。之前不是各种诡异的NullPointer错误,就是NoSuchMethod error,而且都是出现在框架代码中。这些问题,估计不是版本重复就是版本冲突,还有可能是编译时能找到相应的jar包,运行时却找不到或者找到了版本不匹配的jar包。我按照 Testing the Web Layer这里来弄的,可是反反复复都不灵啊。后来呢,可能是运气眷顾了我,改来改去居然成功了,成功的代码大致如下:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void before() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void count() throws Exception {
        this.mockMvc.perform(get("/count?id=1")).andDo(print()).andExpect(status().isOk());
    }
}

然而我并不想用MockMVC,而是真的从数据库获取信息,这时候怎么写捏,我试试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void count() throws Exception {
        System.out.print(restTemplate.getForObject("/my/count", ResultType.class).toString());
    }
}

如果没有这个“webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT”的话,就会出错:
“No qualifying bean of type ...... TestRestTemplate”。

然后以上2种方法都是需要启动本地服务,因为我们是微服务架构,那如果我在某个模块里写了个接口,
只想对该接口的Controller进行测试,并且需要进行自动化,那么很难在自动化环境中启动注册服务、
配置服务这些模块,那么可以使用下面的方法,参考这里:

@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {

    private MockMvc mockMvc;

    @Mock
    private MyService myService;

    @InjectMocks
    private MyController myController;

    @Before
    public void before() {
        mockMvc = MockMvcBuilders.standaloneSetup(myController).build();
    }

    @Test
    public void test_OK() throws Exception {
        MockHttpServletResponse response = this.mockMvc.perform(
                get("/my/count?id=1")).andReturn().getResponse();

        assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
    }

    @Test
    public void test_NOT_FOUND() throws Exception {
        MockHttpServletResponse response = this.mockMvc.perform(
                get("/my/count/test?id=1")).andReturn().getResponse();

        assertThat(response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND.value());
    }

    @Test
    public void test_METHOD_NOT_ALLOWED() throws Exception {
        MockHttpServletResponse response = this.mockMvc.perform(
                get("/my/count1?id=1")).andReturn().getResponse();

        assertThat(response.getStatus()).isEqualTo(HttpStatus.METHOD_NOT_ALLOWED.value());
    }
}

发表评论

电子邮件地址不会被公开。