单元测试总结

Posted zkk502

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单元测试总结相关的知识,希望对你有一定的参考价值。

单元测试

1 为什么要进行单元测试

  1. 单元测试可以有效地测试某个程序模块的行为,是未来重构代码的信心保证。
  2. 单元测试的测试用例要覆盖常用的输入组合、边界条件和异常。
  3. 单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug
  4. 单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug

2 测试框架

Junit+mockito+assertj

3 使用框架

3.1 项目引入相关jar

a. springboot框架,maven引入spring-boot-starter-test即可

   <dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-test</artifactId>

</dependency>

b.springmvc框架maven引入以下依赖:

<dependency>

      <groupId>org.mockito</groupId>

      <artifactId>mockito-all</artifactId>

    </dependency>

    <dependency>

      <groupId>org.assertj</groupId>

      <artifactId>assertj-core</artifactId>

    </dependency>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

    </dependency>

3.2 编写测试类骨架

a. 针对要测试的类,在test包下创建对应main的包名,并将class的名称命名为以Test结尾的名称;

例如:要针对com.tasly.share.core.score UserScoreService接口进行单元测试,需要在test包下建立com.tasly.share.core.score UserScoreServiceTest类。

b. 配置该类的测试运行环境

一种方式:直接在类上增加@RunWith(MockitoJUnitRunner.class)

例如:@RunWith(MockitoJUnitRunner.class)

public class UserScoreServiceTest  {}

第二种方式:测试类统一继承同一个父类,父类上增加@RunWith(MockitoJUnitRunner.class)注解。

例如: public class UserScoreServiceTest extends AbstractUnitTest {}

        

       @RunWith(MockitoJUnitRunner.class)

public abstract class AbstractUnitTest {}

推荐使用第二种方式。

3.3 测试类中增加测试方法

a. 方法访问级别必须是public

b. 返回类型必须是void

c. 方法名字最好是和要测试的方法名相同或者意义比较贴近。

d. 方法上需要增加@Test注解

例如:

    @Test

public void getScoreByUid(){

}

3.4 增加@InjectMocks@Mock成员变量

a. 需要进行单元测试的类需要通过@InjectMocks 注入;

方式有2中:

其一: 注入接口 new出接口的子类

例如:

@InjectMocks

    private UserScoreService userScoreService = new UserScoreServiceImpl();

其二: 直接注入子类

例如:

@InjectMocks

    private UserScoreServiceImpl userScoreService;

b. 测试类需要用到的类 需要通过@Mock注入,包括其他的servicerepository等等;

例如:

    @Mock

    private ShareUserScoreRepository scoreRepository;

 

    @Mock

    private UserScoreLogService userScoreLogService;

3.5 静态导入MockitoMatchers,Assertions类,简化使用

import static org.assertj.core.api.Assertions.*;

import static org.mockito.Matchers.*;

import static org.mockito.Mockito.*;

 

3.6 实现测试用例方法

根据业务场景自行编写测试代码;

例如:

@Test

    public void getScoreByUid(){

 when(scoreRepository.selectByPrimaryKey(anyInt())).thenReturn(MockFactory.gennerate(ShareUserScore.class));

        ShareUserScore scoreByUid = userScoreService.getScoreByUid(1);

        assertThat(scoreByUid).isNotNull();

}

 

MockFactory工厂方法见附录。

3.7 期望值进行断言

可以使用assertThat verify 进行返回值的断言。

其他方法自行查阅相关文档。

3.8 针对跑出的异常可以通过全局设置

@Test(expected = RuntimeException.class)

附录

@UtilityClass
public class MockFactory {

    public <T> List<T> gennerate(Class<T> tClass, int size) {
        return gennerate(gennerate(tClass), size);
    }

    public <T> List<T> gennerate(T t, int size) {
        return Stream.iterate(t, identity())
                .limit(size)
                .collect(Collectors.toList());
    }

    public <T> T gennerate(Class<T> tClass) {
        PodamFactory factory = new PodamFactoryImpl();
        return factory.manufacturePojo(tClass);
    }

}

 

参考文档

https://github.com/hehonghui/mockito-doc-zh#0

集成测试

1 为什么要进行集成测试

1.1集成测试,也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。

1.2实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。一些局部反映不出来的问题,在全局上很可能暴露出来。

2 测试框架

Junit+mockmvc

3 使用框架

3.1 项目引入相关jar

如上单元测试

3.2 编写测试类骨架

a. IDEA提供了快速创建测试类的方法:把光标放到在类名处,然后按alt+enter>create test就可以创建一个测试类

b. 配置该类的测试运行环境

测试类统一继承同一个父类,父类上增加

@RunWith(SpringRunner.class)

@SpringBootTest
@AutoConfigureMockMvc

同时在父类引入 MockMvc

父类例如:

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

    @Autowired
    protected MockMvc mockMvc;


}

子类例如:

public class ProductRestTest extends AbstractIntegrationTest1 {
    @Test
    public void getProductListInfo() throws Exception {
        RequestBuilder requestBuilder;

        requestBuilder = get("/mini/productList");

        mockMvc.perform(requestBuilder)
                .andExpect(status().isOk())

.andExpect(content().string(not("")))
                .andExpect(jsonPath("$.resCode").value("0"))
                .andDo(print());

    }

3.3 使用说明

导入例如 get post put

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;

 

 

mockMVC的用法

1mockMvc.perform执行一个请求;

2MockMvcRequestBuilders.post(http://127.0.0.1:8888/login)构造一个请求

3ResultActions.andExpect添加执行完成后的断言

4ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。

5ResultActions.andReturn表示执行完成后返回相应的结果。

 

Hamcrest

JUnit4.4引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活

例如上例中的not

.andExpect(content().string(not("")))

import static org.hamcrest.Matchers.not;

 











































以上是关于单元测试总结的主要内容,如果未能解决你的问题,请参考以下文章

unittest单元测试框架总结

Java单元测试总结

超详细unittest单元测试框架总结

——单元测试与集成测试 重点部分总结

——单元测试与集成测试 重点部分总结

——单元测试与集成测试 重点部分总结