5.2.1 测试控制器

让我们再审视一下 HomeController。如果你眼神不太好的话,你甚至可能注意不到这些注解,所看到的仅仅是一个简单的 POJO。我们都知道测试 POJO 是很容易的。因此,我们可以编写一个简单的类来测试 HomeController,如下所示:

程序清单 5.5 HomeControllerTest:测试 HomeController
package spittr.web;

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import spittr.web.HomeController;

public class HomeControllerTest {

  @Test
  public void testHomePage() throws Exception {
    HomeController controller = new HomeController();
    assertEuqals("home", controller.home());
  }

}

程序清单 5.5 中的测试很简单,但它只测试了 home() 方法中会发生什 么。在测试中会直接调用 home() 方法,并断言返回包含 home 值的 String。它完全没有站在 Spring MVC 控制器的视角进行测试。这个测试没有断言当接收到针对 / 的 GET 请求时会调用 home() 方法。因为它返回的值就是 home,所以也没有真正判断 home 是视图的名称。

不过从 Spring 3.2 开始,我们可以按照控制器的方式来测试 Spring MVC 中的控制器了,而不仅仅是作为 POJO 进行测试。Spring 现在包含了一种 mock Spring MVC 并针对控制器执行 HTTP 请求的机制。这样的话,在测试控制器的时候,就没有必要再启动 Web 服务器和 Web 浏览器 了。

为了阐述如何测试 Spring MVC 的控制器,我们重写 HomeControllerTest 并使用 Spring MVC 中新的测试特性。程序清单 5.6 展现了新的HomeController-Test。

程序清单 5.6 改进 HomeControllerTest
package spittr.web;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;

import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;

import spittr.web.HomeController;

public class HomeControllerTest {

  @Test
  public void testHomePage() throws Exception {
    HomeController controller = new HomeController();
    MockMvc mockMvc = standaloneSetup(controller).build();
    mockMvc.perform(get("/"))
           .andExpect(view().name("home"));
  }

}

尽管新版本的测试只比之前版本多了几行代码,但是它更加完整地测试了 HomeController。这次我们不是直接调用 home() 方法并测试它的返回值,而是发起了对 / 的 GET 请求,并断言结果视图的名称为 home。它首先传递一个 HomeController 实例到 MockMvcBuilders.standaloneSetup() 并调用 build() 来构建 MockMvc 实例。然后它使用 MockMvc 实例来执行针对 / 的 GET 请求并设置期望得到的视图名称。

Last updated