Unit Testing
依赖注入使代码更独立于容器,揭示 POJO 的可测试性。通过模拟对象、专门的测试支持类和 Spring 的体系结构建议,单元测试可以轻松进行,隔离代码并提高效率。模拟对象和测试支持类允许在不涉及运行时基础架构的情况下测试代码,从而提高开发效率。
依赖注入应该可以让你的代码比使用传统的 J2EE/Java EE 开发更不依赖于容器。构成你的应用程序的 POJO 应该可以在 JUnit 或 TestNG 测试中进行测试,其中对象是使用 new
运算符实例化的,而无需 Spring 或任何其他容器。你可以使用 mock objects (结合其他有价值的测试技术)来孤立地测试你的代码。如果你遵循 Spring 的架构建议,生成的干净分层和你的代码库的组件化将有助于更轻松地进行单元测试。例如,你可以通过存根或模拟 DAO 或存储库接口来测试服务层对象,而无需在运行单元测试时访问持久性数据。
Dependency injection should make your code less dependent on the container than it would
be with traditional J2EE / Java EE development. The POJOs that make up your application
should be testable in JUnit or TestNG tests, with objects instantiated by using the new
operator, without Spring or any other container. You can use mock objects
(in conjunction with other valuable testing techniques) to test your code in isolation.
If you follow the architecture recommendations for Spring, the resulting clean layering
and componentization of your codebase facilitate easier unit testing. For example,
you can test service layer objects by stubbing or mocking DAO or repository interfaces,
without needing to access persistent data while running unit tests.
真正的单元测试通常运行得非常快,因为没有运行时基础架构要设置。强调作为开发方法的一部分而进行的真正的单元测试可以提高你的工作效率。你可能不需要此测试章节部分来帮助你为基于 IoC 的应用程序编写有效的单元测试。然而,对于某些单元测试场景,Spring 框架提供了模拟对象和测试支持类,其中介绍的内容见本章节。
True unit tests typically run extremely quickly, as there is no runtime infrastructure to set up. Emphasizing true unit tests as part of your development methodology can boost your productivity. You may not need this section of the testing chapter to help you write effective unit tests for your IoC-based applications. For certain unit testing scenarios, however, the Spring Framework provides mock objects and testing support classes, which are described in this chapter.
Mock Objects
Spring 包含许多专用于模拟的包:
Spring includes a number of packages dedicated to mocking:
Environment
org.springframework.mock.env
包含`Environment` 和 PropertySource
抽象的模拟实现(见Bean Definition Profiles和PropertySource
Abstraction)。MockEnvironment
和 MockPropertySource
对于开发对环境特定属性有依赖关系的代码的容器外测试非常有用。
The org.springframework.mock.env
package contains mock implementations of the
Environment
and PropertySource
abstractions (see
Bean Definition Profiles
and PropertySource
Abstraction).
MockEnvironment
and MockPropertySource
are useful for developing
out-of-container tests for code that depends on environment-specific properties.
JNDI
org.springframework.mock.jndi
包包含 JNDI SPI 的部分实现,你可以使用该部分实现为测试套件或独立应用程序设置一个简单的 JNDI 环境。例如,如果 JDBC DataSource
实例在测试代码中与它们在 Jakarta EE 容器中的相同 JNDI 名称绑定,你就可以在测试场景中重用应用程序代码和配置,而无需进行修改。
The org.springframework.mock.jndi
package contains a partial implementation of the JNDI
SPI, which you can use to set up a simple JNDI environment for test suites or stand-alone
applications. If, for example, JDBC DataSource
instances get bound to the same JNDI
names in test code as they do in a Jakarta EE container, you can reuse both application code
and configuration in testing scenarios without modification.
包中的模拟 JNDI 支持 org.springframework.mock.jndi
在 Spring Framework 5.2 中正式弃用,取而代之的是来自第三方(如 Simple-JNDI)的完整解决方案。
The mock JNDI support in the org.springframework.mock.jndi
package is
officially deprecated as of Spring Framework 5.2 in favor of complete solutions from third
parties such as Simple-JNDI.
Servlet API
org.springframework.mock.web
包含一组全面的 Servlet API 模拟对象,这些对象对于测试 Web 上下文、控制器和过滤器很有用。这些模拟对象的目标是与 Spring 的 Web MVC 框架一起使用,并且通常比动态模拟对象(如 EasyMock )或备用的 Servlet API 模拟对象(如 MockObjects )更方便使用。
The org.springframework.mock.web
package contains a comprehensive set of Servlet API
mock objects that are useful for testing web contexts, controllers, and filters. These
mock objects are targeted at usage with Spring’s Web MVC framework and are generally more
convenient to use than dynamic mock objects (such as EasyMock)
or alternative Servlet API mock objects (such as MockObjects).
自 Spring 框架 6.0 起, |
Since Spring Framework 6.0, the mock objects in |
MockMvc 基于 servlet API 模拟对象构建,为 Spring MVC 提供了集成测试框架。请参见 MockMvc 。
MockMvc builds on the mock Servlet API objects to provide an integration testing framework for Spring MVC. See MockMvc.
Spring Web Reactive
org.springframework.mock.http.server.reactive
包包含 ServerHttpRequest
和 ServerHttpResponse
的模拟实现,用于在 WebFlux 应用程序中使用。org.springframework.mock.web.server
包包含一个模拟的 ServerWebExchange
,它依赖于那些模拟请求和响应对象。
The org.springframework.mock.http.server.reactive
package contains mock implementations
of ServerHttpRequest
and ServerHttpResponse
for use in WebFlux applications. The
org.springframework.mock.web.server
package contains a mock ServerWebExchange
that
depends on those mock request and response objects.
MockServerHttpRequest
和 MockServerHttpResponse
都从与特定于服务器的实现相同的抽象基类扩展,并与它们共享行为。例如,模拟请求在创建后是不可变的,但你可以使用 ServerHttpRequest
中的 mutate()
方法创建一个已修改的实例。
Both MockServerHttpRequest
and MockServerHttpResponse
extend from the same abstract
base classes as server-specific implementations and share behavior with them. For
example, a mock request is immutable once created, but you can use the mutate()
method
from ServerHttpRequest
to create a modified instance.
为了让模拟响应正确实现写契约并返回写完成处理程序(即 Mono<Void>
),它默认使用带有 cache().then()
的 Flux
,它会缓冲数据并使其在测试中可用于断言。应用程序可以设置自定义写函数(例如,测试一个无限流)。
In order for the mock response to properly implement the write contract and return a
write completion handle (that is, Mono<Void>
), it by default uses a Flux
with
cache().then()
, which buffers the data and makes it available for assertions in tests.
Applications can set a custom write function (for example, to test an infinite stream).
WebTestClient 基于模拟请求和响应构建,以提供在没有 HTTP 服务器的情况下测试 WebFlux 应用程序的支持。客户端还可以用于对正在运行的服务器进行端到端测试。
The WebTestClient builds on the mock request and response to provide support for testing WebFlux applications without an HTTP server. The client can also be used for end-to-end tests with a running server.
Unit Testing Support Classes
Spring 包含许多可以帮助进行单元测试的类。它们分为两类:
Spring includes a number of classes that can help with unit testing. They fall into two categories:
General Testing Utilities
org.springframework.test.util
包包含几个用于单元和集成测试中的通用实用程序。
The org.springframework.test.util
package contains several general purpose utilities
for use in unit and integration testing.
AopTestUtils
是一个 AOP 相关的实用程序方法集合。您可以使用这些方法引用隐藏在 Spring 代理之后的底层目标对象。例如,如果您使用 EasyMock 或 Mockito 等库将 Bean 配置为动态模拟,并且该模拟包含在 Spring 代理中,那么您可能需要直接访问底层模拟以配置对它的期望并执行验证。有关 Spring 的核心 AOP 实用程序,请参阅 AopUtils
和 AopProxyUtils
。
AopTestUtils
is a collection of
AOP-related utility methods. You can use these methods to obtain a reference to the
underlying target object hidden behind one or more Spring proxies. For example, if you
have configured a bean as a dynamic mock by using a library such as EasyMock or Mockito,
and the mock is wrapped in a Spring proxy, you may need direct access to the underlying
mock to configure expectations on it and perform verifications. For Spring’s core AOP
utilities, see AopUtils
and
AopProxyUtils
.
ReflectionTestUtils
是一个基于反射的实用程序方法集合。您可以在需要更改常量值、设置非 public
字段、调用非 public
setter 方法或在测试应用程序代码(用于以下用例)时调用非 public
配置或生命周期回调方法的测试方案中使用这些方法:
ReflectionTestUtils
is a
collection of reflection-based utility methods. You can use these methods in testing
scenarios where you need to change the value of a constant, set a non-public
field,
invoke a non-public
setter method, or invoke a non-public
configuration or lifecycle
callback method when testing application code for use cases such as the following:
-
ORM frameworks (such as JPA and Hibernate) that condone
private
orprotected
field access as opposed topublic
setter methods for properties in a domain entity. -
Spring’s support for annotations (such as
@Autowired
,@Inject
, and@Resource
), that provide dependency injection forprivate
orprotected
fields, setter methods, and configuration methods. -
Use of annotations such as
@PostConstruct
and@PreDestroy
for lifecycle callback methods.
TestSocketUtils
是一个简单的实用程序,用于发现 localhost
上可用的 TCP 端口,以便在集成测试场景中使用。
TestSocketUtils
is a simple
utility for finding available TCP ports on localhost
for use in integration testing
scenarios.
|
Spring MVC Testing Utilities
org.springframework.test.web
包含 ModelAndViewAssert
,您可以将其与 JUnit、TestNG 或任何其他测试框架结合使用,以对处理 Spring MVC ModelAndView
对象的单元测试。
The org.springframework.test.web
package contains
ModelAndViewAssert
, which you
can use in combination with JUnit, TestNG, or any other testing framework for unit tests
that deal with Spring MVC ModelAndView
objects.
Unit testing Spring MVC Controllers
要将你的 Spring MVC |
Unit testing Spring MVC Controllers
To unit test your Spring MVC |