设置选择

MockMvc 可以通过两种方式进行设置。一种是直接指向要测试的控制器,并以编程方式配置 Spring MVC 基础设施。另一种是指向包含 Spring MVC 和控制器基础设施的 Spring 配置。

要为测试特定控制器设置 MockMvc,请使用以下方法

  • Java

  • Kotlin

class MyWebTests {

	MockMvc mockMvc;

	@BeforeEach
	void setup() {
		this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
	}

	// ...

}
class MyWebTests {

	lateinit var mockMvc : MockMvc

	@BeforeEach
	fun setup() {
		mockMvc = MockMvcBuilders.standaloneSetup(AccountController()).build()
	}

	// ...

}

您也可以在通过 WebTestClient 进行测试时使用此设置,它会委托给与上面显示的相同构建器。

要通过 Spring 配置设置 MockMvc,请使用以下方法

  • Java

  • Kotlin

@SpringJUnitWebConfig(locations = "my-servlet-context.xml")
class MyWebTests {

	MockMvc mockMvc;

	@BeforeEach
	void setup(WebApplicationContext wac) {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
	}

	// ...

}
@SpringJUnitWebConfig(locations = ["my-servlet-context.xml"])
class MyWebTests {

	lateinit var mockMvc: MockMvc

	@BeforeEach
	fun setup(wac: WebApplicationContext) {
		mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
	}

	// ...

}

您也可以在通过 WebTestClient 进行测试时使用此设置,它会委托给与上面显示的相同构建器。

应该使用哪种设置选项?

webAppContextSetup 会加载您的实际 Spring MVC 配置,从而产生更完整的集成测试。由于 TestContext 框架会缓存加载的 Spring 配置,因此它有助于保持测试运行速度快,即使您在测试套件中引入了更多测试也是如此。此外,您可以通过 Spring 配置将模拟服务注入控制器,以专注于测试 Web 层。以下示例声明了一个使用 Mockito 的模拟服务

<bean id="accountService" class="org.mockito.Mockito" factory-method="mock">
	<constructor-arg type="java.lang.Class" value="org.example.AccountService"/>
	<constructor-arg type="java.lang.String" value="accountService"/>
</bean>

然后,您可以将模拟服务注入测试以设置和验证您的期望,如下面的示例所示

  • Java

  • Kotlin

@SpringJUnitWebConfig(locations = "test-servlet-context.xml")
class AccountTests {

	@Autowired
	AccountService accountService;

	MockMvc mockMvc;

	@BeforeEach
	void setup(WebApplicationContext wac) {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
	}

	// ...

}
@SpringJUnitWebConfig(locations = ["test-servlet-context.xml"])
class AccountTests {

	@Autowired
	lateinit var accountService: AccountService

	lateinit var mockMvc: MockMvc

	@BeforeEach
	fun setup(wac: WebApplicationContext) {
		mockMvc = MockMvcBuilders.webAppContextSetup(wac).build()
	}

	// ...

}

另一方面,standaloneSetup 更接近于单元测试。它一次测试一个控制器。您可以使用模拟依赖项手动注入控制器,并且它不涉及加载 Spring 配置。此类测试更侧重于样式,并且更容易查看正在测试的控制器、是否需要任何特定 Spring MVC 配置才能正常工作等等。standaloneSetup 也是编写临时测试以验证特定行为或调试问题的非常便捷的方式。

与大多数“集成测试与单元测试”辩论一样,没有正确或错误的答案。但是,使用 standaloneSetup 意味着需要额外的 webAppContextSetup 测试才能验证您的 Spring MVC 配置。或者,您可以使用 webAppContextSetup 编写所有测试,以始终针对您的实际 Spring MVC 配置进行测试。