有没有可能通过创建一个@Configuration
bean来覆盖通过@FeignClient
注解创建的bean,该bean包含一个用于测试的模拟版本?
我已经试过了,但似乎@FeignClient
bean是最后创建的(或者我认为是这样),因为在我的测试中,我总是注入真实的版本,而不是模拟的版本。在同一个配置文件中,我创建了另一个没有任何注解的bean(除了@Component
),通过使用真实的bean的名称以同样的方式模仿它,它工作得很好。
我试过使用@MockBean
来模拟它,它可以工作,但是项目有一些怪癖,使得另一个Spring上下文的创建破坏了测试。
谢谢.
实际上,我刚刚调试了测试,并意识到,如果我使用与Feign客户端相同的名称,调试器甚至不会在@Configuration
bean中停止以创建模拟版本。将名称更改为其他名称可以工作,但它只是创建了另一个具有新名称的相同类型的bean。这里有我遗漏的配置吗?
编辑2.这是一个示例代码。执行此操作后,我发现BarService
是模拟版本,但FooService
是真实的版本。
@FeignClient(name = "fooService")
public interface FooService {
}
@Component
public class BarService {
}
@Configuration
public class ConfigClass {
@Bean
public FooService fooService() {
return Mockito.mock(FooService.class);
}
@Bean
public BarService barService() {
return Mockito.mock(BarService.class);
}
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest
public class TestClass {
@Autowired
private FooService fooService;
@Autowired
private BarService barService;
@Test
public void test() {
System.out.println(fooService.getClass());
}
}
4条答案
按热度按时间6ljaweal1#
你的问题是由FeignClient bean被定义为
primary
这一事实引起的,就像用@Primary
声明bean一样。所以它比其他正常的豆子有优先权。从Dalston版本中包含的spring-cloud-network1.3.0中,您可以关闭此主配置,如下所示。如果你像上面那样修改你的代码,Mocked bean将被注入到你的测试中。
需要注意的一件事是,当您为FeignClient使用fallback bean时,会使用
primary
选项。如果你有fallback bean,你可能需要指定FeignClient bean with qualifer来获取FeignClient bean over fallback bean。我认为另一种注入mocked bean而不是FeignClient bean进行测试的方法是使用
BeanPostProcessor
,如下所示。l7wslrjt2#
默认情况下,注解
@EnableFeignClients
将为标记为@FeignClient
的接口创建主bean。对每个接口禁用此功能可能会产生副作用,例如当存在回退bean时。为了防止在第一时间创建Feign bean,只需将此注解移动到测试禁用的配置类。
然后用
@ActiveProfiles("test")
注解测试类。mzillmmw3#
如果你能分享你的测试类就太好了。
正如我所理解的,你的问题是你需要在测试中重写一个bean。
要做到这一点,您可以参考以下问题:
Overriding an Autowired Bean in Unit Tests
jljoyd4f4#
这是一个bug,已在2.2.3 Feign中修复。