首页 » Spring Boot实战 » Spring Boot实战全文在线阅读

《Spring Boot实战》5.3 用CLI运行测试

关灯直达底部

测试是软件项目的重要组成部分,Spring Boot CLI当然没有忽略测试。因为基于CLI的应用程序并未涉及传统的构建系统,所以CLI提供了一个test命令来运行测试。

在试验test命令前,你先要写一个测试。测试可以放在项目中的任何位置。我建议将其与主要组件分开放置,最好放在一个子目录里。这个子目录的名字随意。我在这里将其命名为tests:

$ mkdir tests  

在tests目录里,创建一个名为ReadingListControllerTest.groovy的新Groovy脚本,编写针对ReadingListController的测试。代码清单5-3是个简单的测试,测试控制器能否正确处理HTTP GET请求。

代码清单5-3 ReadingListController的Groovy测试

import org.springframework.test.web.servlet.MockMvcimport static    org.springframework.test.web.servlet.setup.MockMvcBuilders.*import static org.springframework.test.web.servlet.request.                                             MockMvcRequestBuilders.*import static org.springframework.test.web.servlet.result.                                             MockMvcResultMatchers.*import static org.mockito.Mockito.*class ReadingListControllerTest {  @Test  void shouldReturnReadingListFromRepository {    List<Book> expectedList = new ArrayList<Book>    expectedList.add(new Book(        id: 1,        reader: /"Craig/",        isbn: /"9781617292545/",        title: /"Spring Boot in Action/",        author: /"Craig Walls/",        description: /"Spring Boot in Action is .../"      ))  def mockRepo = mock(ReadingListRepository.class)    ←---模拟 ReadingListRepository  when(mockRepo.findByReader(/"Craig/")).thenReturn(expectedList)  def controller =      new ReadingListController(readingListRepository: mockRepo)  MockMvc mvc = standaloneSetup(controller).build  mvc.perform(get(/"//"))                   ←---执行并测试GET请求    .andExpect(view.name(/"readingList/"))    .andExpect(model.attribute(/"books/", expectedList))  }}  

如你所见,这就是个简单的JUnit测试,使用了Spring的模拟MVC测试支持功能,对控制器发起GET请求。最先设置的是ReadingListRepository的一个模拟实现,它会返回一个包含单一Book项的列表。随后,测试创建了一个ReadingListController实例,将模拟仓库注入readingListRepository属性。最后,配置了一个MockMvc对象,发起GET请求,对期望的视图名称和模型内容进行断言。

但是,此处运行测试要比说明测试更重要。使用CLI的test命令,可以像下面这样在命令行里执行测试:

$ spring test tests/ReadingListControllerTest.groovy  

本例中,我明确选中了ReadingListControllerTest作为要运行的测试。如果tests/目录里有多个测试,你想要全部运行,可以在test命令中指定目录名:

$ spring test tests  

如果你倾向于编写Spock说明而非JUnit测试,那么你一定会很高兴,因为CLI的test命令也可以运行Spock说明,代码清单5-4的ReadingListControllerSpec就演示了这一功能。

代码清单5-4 测试ReadingListController的Spock说明

import org.springframework.test.web.servlet.MockMvcimport static    org.springframework.test.web.servlet.setup.MockMvcBuilders.*import static org.springframework.test.web.servlet.request.                                             MockMvcRequestBuilders.*import static org.springframework.test.web.servlet.result.                                             MockMvcResultMatchers.*import static org.mockito.Mockito.*class ReadingListControllerSpec extends Specification {  MockMvc mockMvc  List<Book> expectedList  def setup {    expectedList = new ArrayList<Book>    expectedList.add(new Book(      id: 1,      reader: /"Craig/",      isbn: /"9781617292545/",      title: /"Spring Boot in Action/",      author: /"Craig Walls/",      description: /"Spring Boot in Action is .../"    ))    def mockRepo = mock(ReadingListRepository.class)     ←---模拟的ReadingListRepository    when(mockRepo.findByReader(/"Craig/")).thenReturn(expectedList)    def controller =        new ReadingListController(readingListRepository: mockRepo)    mockMvc = standaloneSetup(controller).build  }  def /"Should put list returned from repository into model/" {    when:      def response = mockMvc.perform(get(/"//"))    ←---执行GET请求    then:      response.andExpect(view.name(/"readingList/"))              .andExpect(model.attribute(/"books/", expectedList))     ←---测试结果  }}  

ReadingListControllerSpec只是简单地把 ReadingListControllerTest从JUnit测试翻译成了Spock说明。如你所见,它只是直白地表述了这么一个过程。对“/”出现GET请求时,响应中应该包含名为readingList的视图。模型里的books键所对应的就是期待的图书列表。

Spock说明也可以通过spring test tests来运行ReadingListControllerSpec。运行方式和基于JUnit的测试如出一辙。

一旦写好代码,通过了全部测试,你就该部署项目了。让我们来看看Spring Boot CLI是如何帮助产生一个可部署的产物的。