两个基于spring的单元测试简单样例

单元测试,从必定程度上能够看出一个同窗达到的层次。但又不彻底是,有时可能只是一个思考方式的转变。单元测试有很是多的工具供选择,在java中,junit无疑是比较经常使用的。本文列出,junit在spring中的使用样例,供参考。java

 

1:单元测试主要方式web

这里仅说咱们经常使用的单元测试的场景,或者是我本身经常使用的场景,主要分为4大类:spring

1. 对外提供的接口级别的测试,如rest-api, 主要用于保证对外提供的接口符合预期, 而非等到别人调用时才发现异常; json

2. serivce 级别的单元测试, 主要用于保证service功能正常;api

3. 静态方法的测试, 主要用于测试一些工具类符合预期,这类测试通常比较简单;springboot

4. mock接口实现测试, 这类测试每每最复杂, 通常是为测试复杂场景, 但又要保证影响因素单一, 保证测试的有效性, 要求既要mock得少也要求mock得合适, 最难;mvc

通常还有对环境初始化时的运行,和结束测试时的清理工做,即setup() 和teardow(). 在junit中就体现为两个注解:@Before 和 @After 。app

实际上,除了最后一种测试是比较体系化和完备的以外,前几种也许都不是那么细致,至少通常测试不到某个很小的点上,或者说场景不一致。api,service通常会涉及到复杂的外部系统调用,一是依赖多二是速度慢,而尽可能保持本地化测试中一个最佳实践。但记住一点,单元测试应该基于行为,而非基于实现。框架

2. springmvc 的单元测试样例ide

这里主要说的是低版本的springmvc, 里面依赖还比较原始, 因此须要单独讲讲。其依赖包可以下参考:

                    junit            junit            4.12            test                            org.hamcrest            hamcrest-core            1.3                            org.hamcrest            hamcrest-library            1.3                            org.mockito            mockito-all            1.9.5            test

测试用例样例以下:(主要注意必要时引用 servlet的配置就行,不然可能找不到对应的controller)

@RunWith(SpringJUnit4Cla***unner.class)@WebAppConfiguration@ContextConfiguration({"classpath:applicationContext.xml",                        "classpath:applicationContext-servlet.xml"})public class SpringMvcTest {
    @Autowired    private WebApplicationContext wac;
    private MockMvc mockMvc;
    @Before    public void before() throws Exception {        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();    }
    // 对外提供的接口级别的测试 @Before  @After    @Test    public void tesaDataAddKeyword() throws Exception {        TestObj tobj;        MvcResult mvcResult;        String responseResult;        JSONObject resultObj;        tobj = new TestObj();        tobj.setXX(302L);        mvcResult = mockMvc.perform(                MockMvcRequestBuilders.post("/test/add")                        .contentType("application/json")                        .characterEncoding("utf-8")                        .content(JSONObject.toJSONString(tobj)))                .andExpect(MockMvcResultMatchers.status().is(200))                .andReturn();        responseResult = mvcResult.getResponse().getContentAsString();        System.out.println("接口返回结果:" + responseResult);        resultObj = JSONObject.parseObject(responseResult);        Assert.assertNotNull("响应结果为空", resultObj);        Assert.assertThat("正常插入失败",                resultObj.getInteger("status"), is(1));
    }

    @Resource    private TestService testService;
    // serivce 级别的单元测试    @Test    public void testPureKeyword() {        TestObj tObj = new TestObj();        tObj.setXXX(302L);        try {            testService.checkKeyWord(tObj);        }        catch (BizException e) {            Assert.assertEquals("错误码返回不正确", 4001021, e.getErrCode());        }    }
    // 静态方法的测试    @Test    public void testUiExtract() {        String ruleEL;        ParsedClause parsedClause;
        ruleEL = "ui_extract($123, 'md') = '02-01'";
        parsedClause = SyntaxParser.parse(ruleEL);
        Assert.assertEquals("数量解析不正确",                1, parsedClause.getLabelIdMapping().size());        Assert.assertEquals("解析UPP结果不正确",                "string.substring($123 , 5, 10) = '02-01'",                parsedClause.translateTo(DialectTypeEnum.ES));        Assert.assertEquals("解析结果不正确",                "substr($123 , 5, 5) = '02-01'",                parsedClause.translateTo(DialectTypeEnum.HIVE));
    }
    // mock接口实现测试    @Test    public void testMockInterface() {
        List mockList = Mockito.mock(List.class);        mockList.add("1");        // 返回null,说明并无调用真正的方法        Assert.assertNull("mock没有返回null", mockList.get(0));        Mockito.when(mockList.size()).thenReturn(100);//stub        // size() method was stubbed,返回100        Assert.assertThat("mock.size未返回预期值",                    mockList.size(), is(100));
        //test for Spy        List list = new LinkedList();        List spy = Mockito.spy(list);
        //optionally, you can stub out some methods:        Mockito.when(spy.size()).thenReturn(100);
        //using the spy calls real methods        spy.add("one");        spy.add("two");
        //prints "one" - the first element of a list        System.out.println(spy.get(0));
        //size() method was stubbed - 100 is printed        System.out.println(spy.size());    }
    // 预期发生异常的场景测试    @Test(expected = BizException.class)    public void testMethodThrow() {        SyntaxParser.parse(null);    }
}

即对上面4种场景的简单实现样例。

3. springboot的单元测试样例

springboot为咱们省去了许多的依赖问题,因此不会很麻烦。只需引入 test 包,其余相应依赖就下来了。并且通常都是demo代码里默认带有的依赖:

                    org.springframework.boot            spring-boot-starter-test            test                                                org.junit.vintage                    junit-vintage-engine

其使用样例则也会更简单,一个注解搞定了。

@RunWith(SpringRunner.class)@SpringBootTest@AutoConfigureMockMvcpublic class DemoBatchDataControllerTest {
    @Autowired    private MockMvc mockMvc;
    @Test    public void testApi1() throws Exception {        MvcResult result = mockMvc.perform(get("/demo/test1"))                            .andExpect(status().isOk())                            .andReturn();        Assert.assertThat("结果不正确",                 result.getResponse().getContentAsString(), containsString("ok"));    }
    // 其余同springmvc

}

可见springboot确实简单了许多。但框架始终只是框架,须要用户注入灵魂,才能在其上面玩出花样来。  

测试驱动或者测试先行开发,是一种比较好的实践,可让咱们少走弯路,且更自信。

相关文章
相关标签/搜索