@SpringBootTest(类 = SomeController.class) 和@WebMvcTest(SomeController.class) 的区别
difference between @SpringBootTest(classes = SomeController.class) and @WebMvcTest(SomeController.class)
我知道使用 @SpringbootTest
我在测试期间提高了整个 spring 上下文,或者在我的情况下使用 @SpringBootTest(classes = SomeController.class)
我只提高了一个 bean -> SomeController。如果这个控制器有一些依赖项,我需要模拟它们。使用注释 @WebMvcTest(SoneController.class)
我将(根据我的知识)实现相同的目标。
问题是:提供的示例中使用的这两个注释之间是否有任何区别?
我认为只要阅读这两个注释的 Javadoc 就足以回答您的问题:
1. @WebMvcTest
可用于仅关注 Spring MVC 组件的 Spring MVC 测试的注释。
使用此注释将禁用完全自动配置,而是仅应用与 MVC 测试相关的配置(即 @Controller
、@ControllerAdvice
、@JsonComponent
、Converter/GenericConverter、过滤器、WebMvcConfigurer 和 HandlerMethodArgumentResolver bean 但不是 @Component
、@Service
或 @Repository
bean)。
默认情况下,带有 @WebMvcTest
注释的测试也将自动配置 Spring 安全和 MockMvc(包括对 HtmlUnit WebClient 和 Selenium WebDriver 的支持)。为了更细粒度地控制 MockMVC,可以使用 @AutoConfigureMockMvc
注释。
@SpringbootTest
可以在运行 Spring 基于引导的测试的测试 class 上指定的注释。在常规 Spring TestContext 框架之上提供以下功能:
在未定义特定 @ContextConfiguration(loader=...)
时,使用 SpringBootContextLoader 作为默认的 ContextLoader。
未使用嵌套 @Configuration
且未指定显式 classes 时自动搜索 @SpringBootConfiguration。
允许使用 properties 属性定义自定义环境属性。
允许使用 args 属性定义应用程序参数。
提供对不同 webEnvironment 模式的支持,包括启动一个完全 运行 Web 服务器侦听定义或随机端口的能力。
注册一个 TestRestTemplate and/or WebTestClient bean,用于使用完全 运行 网络服务器的网络测试。
@SpringBootTest(classes = SomeController.class)
和 @WebMvcTest(SomeController.class)
有明显区别。
@SpringBootTest(classes = SomeController.class)
- 使用组件 SomeController.class
启动服务器(即像 Tomcat)+ spring 应用程序上下文。除了控制器之外,您通常应该指定上下文配置才能成功启动整个应用程序(例如:当您不指定 classes
时,它会回退到 @SpringBootApplication
)。
@WebMvcTest(SomeController.class)
- 仅启动具有 SomeController.class
.
的应用程序的 web 层
有什么区别?
@SpringBootTest
测试通常是集成测试,您启动完整的 spring-boot 应用程序并针对该黑盒进行测试。您仍然可以通过在注释参数中提供配置、属性、Web 服务器类型等来调整应用程序启动。
但是 @WebMvcTest(SomeController.class)
通常是控制器的单元测试。它们重量轻且速度快。 @Service
类 等依赖项在此类测试中被模拟。
这是一个很好的起点 - https://spring.io/guides/gs/testing-web/
这两种方式之间存在一些细微差别。
但是当你在 spring boot context init 期间遇到 bean 初始化异常或在测试执行期间 NullPointerException
上升等问题时,你会随机发现其中的一部分。
为了让事情更简单,专注于意图。
当你这样写的时候 :
@SpringBootTest(classes = SomeController.class)
您将使 Spring 仅初始化 SomeController bean 实例。
是否需要测试控制器?
可能不会,因为您需要一种使用控制器方法调用控制器的方法。
为此,一个 MockMvc 实例会有所帮助。
使用 WebMvcTest,您可以在测试上下文中额外加载该 bean。
所以那种方式更可取:
@WebMvcTest(SomeController.class)
public class SomeControllerTest{
@Autowired
private MockMvc mvc;
...
}
当然,您可以使用 @SpringBootTest
和一些额外的 classes 获得类似的行为,但这只是一个开销:@WebMvcTest
专用注释就足够了。
最后为什么让你的追随者更难阅读测试class?
通过编织一种使用 spring 启动测试注释的人为方式,很有可能会到达那里。
我知道使用 @SpringbootTest
我在测试期间提高了整个 spring 上下文,或者在我的情况下使用 @SpringBootTest(classes = SomeController.class)
我只提高了一个 bean -> SomeController。如果这个控制器有一些依赖项,我需要模拟它们。使用注释 @WebMvcTest(SoneController.class)
我将(根据我的知识)实现相同的目标。
问题是:提供的示例中使用的这两个注释之间是否有任何区别?
我认为只要阅读这两个注释的 Javadoc 就足以回答您的问题:
1. @WebMvcTest
可用于仅关注 Spring MVC 组件的 Spring MVC 测试的注释。
使用此注释将禁用完全自动配置,而是仅应用与 MVC 测试相关的配置(即 @Controller
、@ControllerAdvice
、@JsonComponent
、Converter/GenericConverter、过滤器、WebMvcConfigurer 和 HandlerMethodArgumentResolver bean 但不是 @Component
、@Service
或 @Repository
bean)。
默认情况下,带有 @WebMvcTest
注释的测试也将自动配置 Spring 安全和 MockMvc(包括对 HtmlUnit WebClient 和 Selenium WebDriver 的支持)。为了更细粒度地控制 MockMVC,可以使用 @AutoConfigureMockMvc
注释。
@SpringbootTest
可以在运行 Spring 基于引导的测试的测试 class 上指定的注释。在常规 Spring TestContext 框架之上提供以下功能:
在未定义特定 @ContextConfiguration(loader=...)
时,使用 SpringBootContextLoader 作为默认的 ContextLoader。
未使用嵌套 @Configuration
且未指定显式 classes 时自动搜索 @SpringBootConfiguration。
允许使用 properties 属性定义自定义环境属性。
允许使用 args 属性定义应用程序参数。 提供对不同 webEnvironment 模式的支持,包括启动一个完全 运行 Web 服务器侦听定义或随机端口的能力。 注册一个 TestRestTemplate and/or WebTestClient bean,用于使用完全 运行 网络服务器的网络测试。
@SpringBootTest(classes = SomeController.class)
和 @WebMvcTest(SomeController.class)
有明显区别。
@SpringBootTest(classes = SomeController.class)
- 使用组件SomeController.class
启动服务器(即像 Tomcat)+ spring 应用程序上下文。除了控制器之外,您通常应该指定上下文配置才能成功启动整个应用程序(例如:当您不指定classes
时,它会回退到@SpringBootApplication
)。
的应用程序的 web 层@WebMvcTest(SomeController.class)
- 仅启动具有SomeController.class
.
有什么区别?
@SpringBootTest
测试通常是集成测试,您启动完整的 spring-boot 应用程序并针对该黑盒进行测试。您仍然可以通过在注释参数中提供配置、属性、Web 服务器类型等来调整应用程序启动。
但是 @WebMvcTest(SomeController.class)
通常是控制器的单元测试。它们重量轻且速度快。 @Service
类 等依赖项在此类测试中被模拟。
这是一个很好的起点 - https://spring.io/guides/gs/testing-web/
这两种方式之间存在一些细微差别。
但是当你在 spring boot context init 期间遇到 bean 初始化异常或在测试执行期间 NullPointerException
上升等问题时,你会随机发现其中的一部分。
为了让事情更简单,专注于意图。
当你这样写的时候 :
@SpringBootTest(classes = SomeController.class)
您将使 Spring 仅初始化 SomeController bean 实例。
是否需要测试控制器?
可能不会,因为您需要一种使用控制器方法调用控制器的方法。
为此,一个 MockMvc 实例会有所帮助。
使用 WebMvcTest,您可以在测试上下文中额外加载该 bean。
所以那种方式更可取:
@WebMvcTest(SomeController.class)
public class SomeControllerTest{
@Autowired
private MockMvc mvc;
...
}
当然,您可以使用 @SpringBootTest
和一些额外的 classes 获得类似的行为,但这只是一个开销:@WebMvcTest
专用注释就足够了。
最后为什么让你的追随者更难阅读测试class?
通过编织一种使用 spring 启动测试注释的人为方式,很有可能会到达那里。