@TestBean
@TestBean
用于测试类中的非静态字段,通过工厂方法提供的实例来覆盖测试的
ApplicationContext
中的特定 bean。
关联的工厂方法名称派生自带注解字段的名称,或者如果指定了 bean 名称,则派生自 bean 名称。工厂方法必须是 static
的,不接受任何参数,并且返回类型与要覆盖的 bean 类型兼容。为了使事情更明确,或者如果你想使用不同的名称,注解允许提供一个特定的方法名称。
默认情况下,带注解字段的类型用于搜索要覆盖的候选 bean。如果多个候选匹配,可以提供 @Qualifier
来缩小要覆盖的候选范围。或者,bean 名称与字段名称匹配的候选也将匹配。
如果不存在对应的 bean,则会创建一个 bean。但是,如果您希望在不存在对应 bean 时测试失败,可以将 enforceOverride
属性设置为 true
—— 例如,@TestBean(enforceOverride = true)
。
要使用按名称覆盖而不是按类型覆盖,请指定注解的 name
属性。
限定符,包括字段名称,用于确定是否需要创建单独的 ApplicationContext
。如果您使用此功能在多个测试中覆盖相同的 bean,请确保一致地命名该字段,以避免创建不必要的上下文。
将 @TestBean
与 @ContextHierarchy
结合使用可能会导致不良结果,因为默认情况下,每个 @TestBean
都将应用于所有上下文层次结构级别。为确保特定的 @TestBean
应用于单个上下文层次结构级别,请将 contextName
属性设置为与配置的 @ContextConfiguration
名称匹配 —— 例如,@TestBean(contextName = "app-config")
。
有关更多详细信息和示例,请参阅
带 bean 覆盖的上下文层次结构。
对 |
以下示例展示了如何使用 @TestBean
注解的默认行为:
- Java
-
class OverrideBeanTests { @TestBean [id="CO1-1"][id="CO1-1"][id="CO1-1"](1) CustomService customService; // test case body... static CustomService customService() { [id="CO1-2"][id="CO1-2"][id="CO1-2"](2) return new MyFakeCustomService(); } }
<1> 标记一个字段,用于覆盖类型为 `CustomService` 的 bean。 <1> 此静态方法的结果将用作实例并注入到该字段中。
在上面的示例中,我们覆盖了类型为 CustomService
的 bean。如果存在多个该类型的 bean,则考虑名为 customService
的 bean。否则,测试将失败,您将需要提供某种限定符来标识要覆盖的 CustomService
bean 中的哪一个。
以下示例使用按名称查找,而不是按类型查找:
-
Java
class OverrideBeanTests {
@TestBean(name = "service", methodName = "createCustomService") [id="CO2-1"][id="CO1-3"][id="CO2-1"](1)
CustomService customService;
// test case body...
static CustomService createCustomService() { [id="CO2-2"][id="CO1-4"][id="CO2-2"](2)
return new MyFakeCustomService();
}
}
1 | 标记一个字段,用于覆盖名称为 service 的 bean,并指定工厂方法名为 createCustomService 。 |
2 | 此静态方法的结果将用作实例并注入到该字段中。 |
为了找到要调用的工厂方法,Spring 会在声明 |
只有 单例 bean 可以被覆盖。任何覆盖非单例 bean 的尝试都将导致异常。
当覆盖由 |