@TestBean

@TestBean 用于测试类中的字段,以使用工厂方法提供的实例覆盖测试的ApplicationContext中的特定 Bean。

关联的工厂方法名称派生自带注解的字段名称,或者如果指定了 Bean 名称则为 Bean 名称。工厂方法必须是static的,不接受任何参数,并且返回类型与要覆盖的 Bean 类型兼容。为了使事情更明确,或者如果您希望使用不同的名称,则该注解允许提供特定的方法名称。

默认情况下,带注解的字段类型用于搜索要覆盖的候选 Bean。如果多个候选对象匹配,则可以使用@Qualifier将候选对象缩小到要覆盖的对象。或者,Bean 名称与字段名称匹配的候选对象将匹配。

如果对应的 Bean 不存在,则将创建一个 Bean。但是,如果您希望在对应的 Bean 不存在时测试失败,您可以将enforceOverride属性设置为true——例如,@TestBean(enforceOverride = true)

要使用按名称覆盖而不是按类型覆盖,请指定注解的name属性。

限定符(包括字段名称)用于确定是否需要创建单独的ApplicationContext。如果您使用此功能在多个测试中覆盖相同的 Bean,请确保一致地命名字段以避免创建不必要的上下文。

以下示例显示了如何使用@TestBean注解的默认行为

  • Java

class OverrideBeanTests {
	@TestBean (1)
	private CustomService customService;

	// test case body...

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

在上面的示例中,我们正在覆盖类型为CustomService的 Bean。如果存在多个该类型的 Bean,则名为customService的 Bean 将被考虑。否则,测试将失败,您需要提供某种限定符来标识要覆盖的CustomService Bean。

以下示例使用按名称查找,而不是按类型查找

  • Java

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

	// test case body...

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

Spring 在测试类、测试类层次结构和封闭类的层次结构(对于@Nested测试类)中搜索要调用的工厂方法。

或者,可以通过其完全限定的方法名称引用外部类中的工厂方法,该方法遵循语法<fully-qualified class name>#<method name>——例如,methodName = "org.example.TestUtils#createCustomService"

只有单例 Bean 才能被覆盖。任何尝试覆盖非单例 Bean 的行为都会导致异常。

覆盖由FactoryBean创建的 Bean 时,FactoryBean将被替换为与@TestBean工厂方法返回的值对应的单例 Bean。