此版本仍在开发中,尚未稳定。如需最新的稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

@TestBean

@TestBean 用于测试类中的非静态字段,以使用工厂方法提供的实例覆盖测试的 ApplicationContext 中的特定bean。spring-doc.cadn.net.cn

与注解字段关联的工厂方法名称是从注解字段的名称派生的,或者如果指定了,则从bean名称派生。工厂方法必须是无参的,不接受任何参数,并且返回类型必须与要覆盖的bean类型兼容。为了使事情更明确,或者如果您希望使用不同的名称,注解允许提供一个特定的方法名称。spring-doc.cadn.net.cn

默认情况下,使用注解字段的类型来搜索要覆盖的候选bean。 如果有多个候选者匹配,可以提供@Qualifier来缩小要覆盖的候选者的范围。或者,其bean名称与字段名称匹配的候选者也将匹配。spring-doc.cadn.net.cn

如果对应的bean不存在,将创建一个bean。但是,如果你想在没有对应bean存在时测试失败,你可以将enforceOverride属性设置为true——例如,@TestBean(enforceOverride = true)spring-doc.cadn.net.cn

要使用按名称覆盖而非按类型覆盖,请在注解中指定name属性。spring-doc.cadn.net.cn

限定符,包括字段的名称,用于确定是否需要创建单独的 ApplicationContext。如果您正在使用此功能在多个测试中覆盖同一个bean,请确保字段名称保持一致,以避免创建不必要的上下文。spring-doc.cadn.net.cn

使用 @TestBean@ContextHierarchy 结合可能会导致不期望的结果,因为每个 @TestBean 默认会应用于所有上下文层次。为了确保特定的 @TestBean 只应用于单个上下文层次,请设置 contextName 属性以匹配配置的 @ContextConfiguration 名称 – 例如,@TestBean(contextName = "app-config")spring-doc.cadn.net.cn

查看 带有bean覆盖的上下文层次结构 以获取更多详细信息和示例。spring-doc.cadn.net.cn

@TestBean 字段或工厂方法的可见性没有限制。spring-doc.cadn.net.cn

因此,这些字段和方法可以根据项目的需要或编码规范为 publicprotected、包私有(默认可见性),或 privatespring-doc.cadn.net.cn

以下示例展示了如何使用@0注解的默认行为:spring-doc.cadn.net.cn

class OverrideBeanTests {
	@TestBean (1)
	CustomService customService;

	// test case body...

	static CustomService customService() { (2)
		return new MyFakeCustomService();
	}
}
1 标记一个字段以覆盖类型为CustomService的bean。
2 此静态方法的结果将用作实例并注入到字段中。

在上述示例中,我们正在覆盖类型为CustomService的bean。如果存在多个该类型的bean,将考虑名为customService的bean。否则,测试将失败,您需要提供某种限定符来标识您想要覆盖的CustomService个bean中的哪一个。spring-doc.cadn.net.cn

以下示例使用了按名称查找,而非按类型查找:spring-doc.cadn.net.cn

class OverrideBeanTests {
	@TestBean(name = "service", methodName = "createCustomService") (1)
	CustomService customService;

	// test case body...

	static CustomService createCustomService() { (2)
		return new MyFakeCustomService();
	}
}
1 标记一个字段以覆盖名为 service 的bean,并指定工厂方法名为 createCustomService
2 此静态方法的结果将用作实例并注入到字段中。

为了定位要调用的工厂方法,Spring会在声明@TestBean字段的类中、其任何一个超类中或实现的接口中进行搜索。如果@TestBean字段在@Nested测试类中声明,那么也会搜索包围它的类层次结构。spring-doc.cadn.net.cn

另外,外部类中的工厂方法可以通过其完全限定的方法名引用,遵循<fully-qualified class name>#<method name>的语法格式——例如,methodName = "org.example.TestUtils#createCustomService"spring-doc.cadn.net.cn

单例bean可被覆盖。尝试覆盖非单例bean将导致异常。spring-doc.cadn.net.cn

在覆盖由FactoryBean创建的bean时,FactoryBean将被替换为与从@TestBean工厂方法返回的值对应的单例bean。spring-doc.cadn.net.cn