当有 2 个相同类型时如何 @MockBean?
How to @MockBean when there are 2 of the same type?
将尝试提供简化的示例(希望我不会在某处搞砸)
假设我有 2 个相同类型的 @Beans,但其中一个被注释了
@Configuration
public class FooProvider {
@Bean
public Foo foo1() {...}
@Bean
@SpecialFoo
public Foo foo2() {...}
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface SpecialFoo {}
在我的应用程序中,Spring 似乎可以接受一个带注释的 bean 和一个未带注释的 bean。注释是@Qualifier
@Configuration
public class BarProvider {
@Bean
public Bar bar1(Foo foo1) {...}
@Bean
public Bar bar2(@SpecialFoo Foo foo2) {...}
}
所有这些都有效。程序加载,Spring 没有抱怨。
但是当我尝试测试它时,问题出现了。
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureWebTestClient
public class MyTest {
@MockBean
Foo foo1;
@MockBean @SpecialFoo
Foo foo2;
}
此时,我收到类似
的错误
No qualifying bean of type 'Foo' available: expected single matching bean but found 2: foo1, foo2
我做错了什么?
特殊要求:我宁愿不必也注释 foo1
或添加 @Qualifier
只是因为有很多地方需要更改。我宁愿默认 bean 是未注释的 bean。
尝试添加:
@Primary
public Foo foo1() {
...
}
像这样
@Configuration
public class FooProvider {
@Bean("foo1")
public Foo foo1() {...}
@Bean("foo2")
public Foo foo2() {...}
}
...
@Autowire
@Qualifier("foo1")
Foo foo1;
@Autowire
@Qualifier("foo2")
Foo foo2;
这是我发现的作品
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureWebTestClient
public class MyTest {
@MockBean(name = "foo1")
Foo foo1;
@MockBean @SpecialFoo
Foo foo2;
}
我需要告诉 Spring 我要用这个 mock 替换哪个 Foo @Bean,方法是给它提供要替换的 bean 的名称。如果 MockBean 具有 @Qualifier
或 @SpecialFoo
限定符注释,则它不需要此命名。所以只有未注释的 bean 需要这个。
在评论中回答我的问题,这两个似乎是等价的:
@MockBean(name = "foo1")
和
@MockBean @Qualifier("foo1")
希望这对其他人有帮助
将尝试提供简化的示例(希望我不会在某处搞砸)
假设我有 2 个相同类型的 @Beans,但其中一个被注释了
@Configuration
public class FooProvider {
@Bean
public Foo foo1() {...}
@Bean
@SpecialFoo
public Foo foo2() {...}
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface SpecialFoo {}
在我的应用程序中,Spring 似乎可以接受一个带注释的 bean 和一个未带注释的 bean。注释是@Qualifier
@Configuration
public class BarProvider {
@Bean
public Bar bar1(Foo foo1) {...}
@Bean
public Bar bar2(@SpecialFoo Foo foo2) {...}
}
所有这些都有效。程序加载,Spring 没有抱怨。
但是当我尝试测试它时,问题出现了。
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureWebTestClient
public class MyTest {
@MockBean
Foo foo1;
@MockBean @SpecialFoo
Foo foo2;
}
此时,我收到类似
的错误No qualifying bean of type 'Foo' available: expected single matching bean but found 2: foo1, foo2
我做错了什么?
特殊要求:我宁愿不必也注释 foo1
或添加 @Qualifier
只是因为有很多地方需要更改。我宁愿默认 bean 是未注释的 bean。
尝试添加:
@Primary
public Foo foo1() {
...
}
像这样
@Configuration
public class FooProvider {
@Bean("foo1")
public Foo foo1() {...}
@Bean("foo2")
public Foo foo2() {...}
}
...
@Autowire
@Qualifier("foo1")
Foo foo1;
@Autowire
@Qualifier("foo2")
Foo foo2;
这是我发现的作品
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureWebTestClient
public class MyTest {
@MockBean(name = "foo1")
Foo foo1;
@MockBean @SpecialFoo
Foo foo2;
}
我需要告诉 Spring 我要用这个 mock 替换哪个 Foo @Bean,方法是给它提供要替换的 bean 的名称。如果 MockBean 具有 @Qualifier
或 @SpecialFoo
限定符注释,则它不需要此命名。所以只有未注释的 bean 需要这个。
在评论中回答我的问题,这两个似乎是等价的:
@MockBean(name = "foo1")
和
@MockBean @Qualifier("foo1")
希望这对其他人有帮助