kan*_*ane 2 java spring dependency-injection mockito spring-boot
将尝试提供简化的示例(希望我不会在某个地方搞砸)
假设我有 2 个相同类型的 @Bean,但其中一个带有注释
@Configuration
public class FooProvider {
@Bean
public Foo foo1() {...}
@Bean
@SpecialFoo
public Foo foo2() {...}
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface SpecialFoo {}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,Spring 似乎可以接受一个带注释的 bean 和一个未注释的 bean。该注解是@Qualifier
@Configuration
public class BarProvider {
@Bean
public Bar bar1(Foo foo1) {...}
@Bean
public Bar bar2(@SpecialFoo Foo foo2) {...}
}
Run Code Online (Sandbox Code Playgroud)
所有这些都有效。程序加载完毕,Spring 并没有抱怨。
但当我尝试测试它时,问题就出现了。
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureWebTestClient
public class MyTest {
@MockBean
Foo foo1;
@MockBean @SpecialFoo
Foo foo2;
}
Run Code Online (Sandbox Code Playgroud)
此时,我收到类似的错误
没有可用的“Foo”类型的合格 bean:预期有单个匹配 bean,但发现了 2 个:foo1、foo2
我究竟做错了什么?
特别要求:我不想foo1也注释或添加,@Qualifier因为它有很多我需要更改的地方。我宁愿默认 bean 是未注释的 bean。
这就是我发现的作品
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureWebTestClient
public class MyTest {
@MockBean(name = "foo1")
Foo foo1;
@MockBean @SpecialFoo
Foo foo2;
}
Run Code Online (Sandbox Code Playgroud)
我需要告诉 Spring 我用这个模拟替换了哪个 Foo @Bean,方法是给 Spring 指定要替换的 bean 的名称。如果MockBean有一个@Qualifier或@SpecialFooQualifier注释,那么它不需要这个命名。所以只有未注释的 bean 才需要这个。
为了回答我在评论中的问题,这两个似乎是等效的:
@MockBean(name = "foo1")
Run Code Online (Sandbox Code Playgroud)
和
@MockBean @Qualifier("foo1")
Run Code Online (Sandbox Code Playgroud)
希望这对其他人有帮助