Differences between Out-of-Container and End-to-End Integration Tests

https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/integration-testing.html#spring-mvc-test-vs-end-to-end-integration-tests

Differences between Out-of-Container and End-to-End Integration Tests
As mentioned earlier Spring MVC Test is built on the Servlet API mock objects from the spring-test module and does not use a running Servlet container. Therefore there are some important differences compared to full end-to-end integration tests with an actual client and server running.

The easiest way to think about this is starting with a blank MockHttpServletRequest. Whatever you add to it is what the request will be. Things that may catch you by surprise are that there is no context path by default, no jsessionid cookie, no forwarding, error, or async dispatches, and therefore no actual JSP rendering. Instead, "forwarded" and "redirected" URLs are saved in the MockHttpServletResponse and can be asserted with expectations.

This means if you are using JSPs you can verify the JSP page to which the request was forwarded, but there won’t be any HTML rendered. In other words, the JSP will not be invoked. Note however that all other rendering technologies which don’t rely on forwarding such as Thymeleaf, Freemarker, and Velocity will render HTML to the response body as expected. The same is true for rendering JSON, XML, and other formats via @ResponseBody methods.

Alternatively you may consider the full end-to-end integration testing support from Spring Boot via @WebIntegrationTest. See the Spring Boot reference.

There are pros and cons for each approach. The options provided in Spring MVC Test are different stops on the scale from classic unit testing to full integration testing. To be certain, none of the options in Spring MVC Test fall under the category of classic unit testing, but they are a little closer to it. For example, you can isolate the web layer by injecting mocked services into controllers, in which case you’re testing the web layer only through the DispatcherServlet but with actual Spring configuration, just like you might test the data access layer in isolation from the layers above. Or you can use the standalone setup focusing on one controller at a time and manually providing the configuration required to make it work.

Another important distinction when using Spring MVC Test is that conceptually such tests are on the inside of the server-side so you can check what handler was used, if an exception was handled with a HandlerExceptionResolver, what the content of the model is, what binding errors there were, etc. That means it’s easier to write expectations since the server is not a black box as it is when testing it through an actual HTTP client. This is generally an advantage of classic unit testing, that it’s easier to write, reason about, and debug but does not replace the need for full integration tests. At the same time it’s important not to lose sight of the fact that the response is the most important thing to check. In short, there is room here for multiple styles and strategies of testing even within the same project.

== GOOGLE 翻译 ==

容器外和端到端集成测试之间的差异
如前所述,Spring MVC Test构建于spring-test模块的Servlet API模拟对象之上,并不使用正在运行的Servlet容器。因此,与实际客户端和服务器运行的完整端到端集成测试相比,存在一些重要差异。

考虑这一点的最简单方法是从一个空白的MockHttpServletRequest开始。无论你添加什么,请求都是什么。令您惊讶的是,默认情况下没有上下文路径,没有jsessionid cookie,没有转发,错误或异步调度,因此没有实际的JSP呈现。相反,“转发”和“重定向”URL保存在MockHttpServletResponse中,并且可以满足期望。

这意味着如果您使用JSP,则可以验证请求转发到的JSP页面,但不会呈现任何HTML。换句话说,不会调用JSP。但请注意,所有其他不依赖转发的渲染技术(如Thymeleaf,Freemarker和Velocity)都会按预期将HTML呈现给响应主体。通过@ResponseBody方法渲染JSON,XML和其他格式也是如此。

或者,您可以考虑通过@WebIntegrationTest从Spring Boot获得完整的端到端集成测试支持。请参阅Spring Boot参考。

每种方法都有利弊。 Spring MVC Test中提供的选项在从经典单元测试到完全集成测试的规模上是不同的停止。可以肯定的是,Spring MVC Test中没有一个选项属于经典单元测试类别,但它们更接近它。例如,您可以通过将模拟服务注入控制器来隔离Web层,在这种情况下,您只通过DispatcherServlet测试Web层,但使用实际的Spring配置,就像您可以独立于层测试数据访问层一样以上。或者,您可以一次使用专注于一个控制器的独立设置,并手动提供使其工作所需的配置。

使用Spring MVC Test时的另一个重要区别是概念上这样的测试位于服务器端内部,因此您可以检查使用了什么处理程序,是否使用HandlerExceptionResolver处理异常,模型的内容是什么,绑定是什么这意味着更容易编写期望,因为服务器不是黑盒子,因为它是通过实际的HTTP客户端测试它。这通常是经典单元测试的一个优点,它更容易编写,推理和调试,但不能取代完全集成测试的需要。与此同时,重要的是不要忽视响应是最重要的检查事实。简而言之,即使在同一个项目中,也存在多种样式和测试策略的空间。

 

 

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications

 

Testing Spring Boot Applications
A Spring Boot application is a Spring ApplicationContext, so nothing very special has to be done to test it beyond what you would normally do with a vanilla Spring context.

[Note]
External properties, logging, and other features of Spring Boot are installed in the context by default only if you use SpringApplication to create it.

Spring Boot provides a @SpringBootTest annotation, which can be used as an alternative to the standard spring-test @ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests through SpringApplication. In addition to @SpringBootTest a number of other annotations are also provided for testing more specific slices of an application.

[Tip]
If you are using JUnit 4, don’t forget to also add @RunWith(SpringRunner.class) to your test, otherwise the annotations will be ignored. If you are using JUnit 5, there’s no need to add the equivalent @ExtendWith(SpringExtension) as @SpringBootTest and the other @…Test annotations are already annotated with it.

By default, @SpringBootTest will not start a server. You can use the webEnvironment attribute of @SpringBootTest to further refine how your tests run:

MOCK(Default) : Loads a web ApplicationContext and provides a mock web environment. Embedded servers are not started when using this annotation. If a web environment is not available on your classpath, this mode transparently falls back to creating a regular non-web ApplicationContext. It can be used in conjunction with @AutoConfigureMockMvc or @AutoConfigureWebTestClient for mock-based testing of your web application.
RANDOM_PORT: Loads a WebServerApplicationContext and provides a real web environment. Embedded servers are started and listen on a random port.
DEFINED_PORT: Loads a WebServerApplicationContext and provides a real web environment. Embedded servers are started and listen on a defined port (from your application.properties) or on the default port of 8080.
NONE: Loads an ApplicationContext by using SpringApplication but does not provide any web environment (mock or otherwise).
[Note]
If your test is @Transactional, it rolls back the transaction at the end of each test method by default. However, as using this arrangement with either RANDOM_PORT or DEFINED_PORT implicitly provides a real servlet environment, the HTTP client and server run in separate threads and, thus, in separate transactions. Any transaction initiated on the server does not roll back in this case.

[Note]
@SpringBootTest with webEnvironment = WebEnvironment.RANDOM_PORT will also start the management server on a separate random port if your application uses a different port for the management server.

== GOOGLE 翻译 ==

测试Spring Boot应用程序
Spring Boot应用程序是一个Spring ApplicationContext,因此除了通常使用的Spring上下文之外,还没有什么特别的东西可以用来测试它。

[注意]
只有在使用SpringApplication创建Spring Boot的外部属性,日志记录和其他功能时,才会默认安装在上下文中。

Spring Boot提供@SpringBootTest注释,当您需要Spring Boot功能时,它可以用作标准spring-test @ContextConfiguration注释的替代方法。注释通过SpringApplication创建测试中使用的ApplicationContext来工作。除了@SpringBootTest之外,还提供了许多其他注释来测试应用程序的更具体的切片。

[小费]
如果您使用的是JUnit 4,请不要忘记在测试中添加@RunWith(SpringRunner.class),否则将忽略注释。如果您使用的是JUnit 5,则无需将等效的@ExtendWith(SpringExtension)添加为@SpringBootTest,而另一个@ ...测试注释已经使用它进行注释。

默认情况下,@ SpringBootTest不会启动服务器。您可以使用@SpringBootTest的webEnvironment属性来进一步优化测试的运行方式:

MOCK(默认):加载Web ApplicationContext并提供模拟Web环境。使用此批注时,不会启动嵌入式服务器。如果类路径上没有Web环境,则此模式将透明地回退到创建常规非Web ApplicationContext。它可以与@AutoConfigureMockMvc或@AutoConfigureWebTestClient结合使用,以进行基于模拟的Web应用程序测试。
RANDOM_PORT:加载WebServerApplicationContext并提供真实的Web环境。嵌入式服务器启动并在随机端口上侦听。
DEFINED_PORT:加载WebServerApplicationContext并提供真实的Web环境。嵌入式服务器启动并侦听定义的端口(来自您的application.properties)或默认端口8080。
NONE:使用SpringApplication加载ApplicationContext,但不提供任何Web环境(模拟或其他)。
[注意]
如果您的测试是@Transactional,则默认情况下会在每个测试方法的末尾回滚事务。但是,由于使用RANDOM_PORT或DEFINED_PORT这种安排隐式提供了一个真正的servlet环境,因此HTTP客户端和服务器在不同的线程中运行,因此在单独的事务中运行。在这种情况下,在服务器上启动的任何事务都不会回滚。

[注意]
如果您的应用程序使用不同的管理服务器端口,带有webEnvironment = WebEnvironment.RANDOM_PORT的@SpringBootTest也将在单独的随机端口上启动管理服务器。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zonson9999

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值