Spring中测试如何写

最近在实践测试,经常遇到一个问题,就是测试怎么写,测试粒度是怎么样的?所以狂补了一下测试相关的知识。

测试金字塔

测试金字塔将测试进行了分层,越底层的测试,实现成本越低,测试效率更高,可维护性越高,但是业务需求的反映越低


测试金字塔

如图,测试被分成了三层,从下到上分成:Unit层,UI层和Service层。

  • Unit层则是我们常说的单元测试。
  • Service层又可以细分,如(集成测试,功能测试,系统测试,契约测试,端到端测试)。
  • UI层则是用户界面测试。

单元测试

单元测试处于金字塔最底部,这类测试的特点是:

  • 只测试单独的class
  • 只需要有应用的源码,而不需要跑服务实例
  • 够快
  • 不依赖于外部系统(web service,database)且不需要很多/基本没有I/O操作(不用建立数据库)

在Spring boot中主要有三种测试方法

  • Controller测试 - 使用mockMvc
@RunWith(SpringRunner.class)
@WebMvcTest(TaskController.class)
public class TaskControllerTest { 
    @Autowired 
    private MockMvc mockMvc; 
    @MockBean 
    private TaskService taskService; 
    @Test 
    public void should_get_all_tasks_by_getAllTask() throws Exception { 
      given(taskService.getTasks())
        .willReturn(Lists.newArrayList(createTask("test"), createTask("aaa"))); 
       mockMvc.perform(MockMvcRequestBuilders.get("/tasks")) 
        .andExpect(status().isOk())
        .andExpect(jsonPath("$[0].name").value("test")) 
        .andExpect(jsonPath("$[1].name").value("aaa")); 
     } 
    public Task createTask(String name) { 
      Task task = new Task(); 
      task.setName(name); return task; 
    }
 }
  • Service测试 - 使用Mockito
@RunWith(MockitoJUnitRunner.class)
public class TaskServiceTest {
  @InjectMocks
  private TaskService taskService;
  @Mock
  private TaskRepository taskRepository;
  @Test
  public void should_return_all_tasks_when_getAllTasks() {
    given(taskRepository.findAll())
      .willReturn(Lists.newArrayList(createTask("test"), createTask("aaa")));
    List<Task> tasks = taskService.getTasks();

    assertThat(tasks.size(), is(2));
    assertThat(tasks.get(0).getName(), is("test"));
    assertThat(tasks.get(1).getName(), is("aaa"));
  }

  public Task createTask(String name) {
    Task task = new Task();
    task.setName(name);
    return task;
  }
}

repository 测试 - 使用DataJpaTest

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = NONE)
public class TaskRepositoryTest {
  @Autowired
    private TaskRepository taskRepository;

  @Autowired
  private TestEntityManager entityManager;

  @Test
  public void get_all_will_return_all_tasks() {
    List<Task> tasks = taskRepository.findAll();
    assertThat(tasks.size(), is(2));
    assertThat(tasks.get(0).getName(), is("test"));
    assertThat(tasks.get(1).getName(), is("aaa"));
  }
}

基于H2,flywayTest annotation测试的写法。
@FlywayTest可以放在3个地方

  • class上面:单个class 会跑flywayclean 和flywaymigrate
  • setup方法上面:每个测试都会跑flywayclean 和flywaymigrate
  • 单个测试方法上面:单个测试会跑flywayclean 和flywaymigrate
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
@RunWith(SpringRunner.class)
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        FlywayTestExecutionListener.class
})
class FlywayMethodTest {

    @Autowired
    private UserRepository repository;

    @Test
    @FlywayTest
    void contextLoads() {
        assertThat(repository.findAll().size(), is(3));
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,314评论 19 139
  • 本文部分内容及示例来自Google Testing Blog,有兴趣可以在文末点击链接查看原文。 Preface ...
    lshilll阅读 4,503评论 1 8
  • 在正式讲自动化测试之前,我们不妨来先聊聊目前测试团队一般存在的几种模式。 1.1 冰淇淋模式(ice cream ...
    博客已迁移I米阳阅读 10,021评论 13 18
  • 探索生物学是怎么理解大脑和心灵的? 1.大脑的发展 相信知识具有统一性,是迷宫的本体。这种信仰包含这样的假设:人类...
    苏菲小姐的咖啡时光阅读 847评论 0 0
  • 晚七点下班到家,简单洗漱,换好衣服,婆婆还在抱着孩子,公公已经给热好饭菜,端上了饭桌,看着这一切心里满是感...
    童Vs源阅读 1,352评论 0 0