@SpringbootTest
可以在测试期间引用整个Spring上下文,或者在我的情况下,使用@SpringBootTest(classes = SomeController.class)
只会引用一个bean -> SomeController。如果此控制器具有某些依赖项,则需要模拟它们。使用注释@WebMvcTest(SomeController.class)
,我将(根据我的知识)实现相同的目标。问题是:在提供的示例中使用这两个注释之间是否存在任何区别?
@SpringbootTest
可以在测试期间引用整个Spring上下文,或者在我的情况下,使用@SpringBootTest(classes = SomeController.class)
只会引用一个bean -> SomeController。如果此控制器具有某些依赖项,则需要模拟它们。使用注释@WebMvcTest(SomeController.class)
,我将(根据我的知识)实现相同的目标。@SpringBootTest(classes = SomeController.class)
与@WebMvcTest(SomeController.class)
有明显区别。
@SpringBootTest(classes = SomeController.class)
- 启动一个服务器(例如Tomcat)和一个带有组件SomeController.class
的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上下文初始化期间遇到bean初始化异常或在测试执行期间出现NullPointerException
,您才会偶然发现其中的一部分差异。
为了使事情更简单,重点关注意图。
当您编写以下内容时:
@SpringBootTest(classes = SomeController.class)
您需要让Spring仅初始化SomeController bean实例。
测试控制器是否可取?
可能不是,因为您需要一种使用控制器方法调用控制器的方式。
MockMvc实例可以帮助您实现这一点。
使用WebMvcTest,该bean还会在测试上下文中额外加载。
因此,这种方式更可取:
@WebMvcTest(SomeController.class)
public class SomeControllerTest{
@Autowired
private MockMvc mvc;
...
}
当然,您可以使用@SpringBootTest
和一些额外的类获得类似的行为,但这只会增加不必要的负担:专门用于@WebMvcTest
的注释已经足够了。
最后,为什么要让您的读者难以阅读测试类?通过编织一种牵强附会的使用spring boot测试注释的方式,很可能会出现这种情况。
@ContextConfiguration(loader=...)
时。
自动搜索 @SpringBootConfiguration 当嵌套的 @Configuration
没有被使用且没有明确指定类时。
允许使用 properties 属性定义自定义环境属性。
允许使用 args 属性定义应用程序参数。
提供对不同 webEnvironment 模式的支持,包括启动在已定义或随机端口上监听的完全运行的 Web 服务器的能力。
为正在使用完全运行的 Web 服务器的 Web 测试注册 TestRestTemplate 和/或 WebTestClient bean。