java - 使用 @Configuration bean 覆盖 @FeignClient 进行测试

标签 java spring unit-testing mockito feign

是否可以通过创建一个包含用于测试的模拟版本的 @Configuration bean 来覆盖通过 @FeignClient 注解创建的 bean?

我已经尝试过了,但似乎 @FeignClient bean 是最后创建的(或者我认为如此),因为在我的测试中,我总是注入(inject)真实版本而不是模拟版本。在同一个配置文件中,我创建了另一个没有任何注释的 bean(@Component 除外),仅使用真实的名称以相同的方式进行模拟,并且效果很好。

我已经尝试使用 @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());
  }
}

最佳答案

你的问题是由于 FeignClient bean 被定义为 primary 就像用 @Primary 声明一个 bean 一样。所以它比其他普通 bean 有优先权。 从 Dalston 版本中包含的 spring-cloud-netflix 1.3.0 开始,您可以关闭此主要配置,如下所示。

@FeignClient(name = "fooService", primary = false)
public interface FooService {
}

如果您像上面那样更改代码,模拟 bean 将被注入(inject)到您的测试中。

您需要注意的一件事是,当您为 FeignClient 使用后备 bean 时,会使用 primary 选项。如果你有后备 bean,你可能需要用 qualifer 指定 FeignClient bean 来让 FeignClient bean 超过后备 bean。

我认为另一种为测试注入(inject)模拟 bean 而不是 FeignClient bean 的方法是使用 BeanPostProcessor 如下所示。

public static class MockProcessor implements BeanPostProcessor {
         : 
         :
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (/* distinguish your target bean */) 
            return Mockito.mock(FooService.class);
        return bean;
    }
}

关于java - 使用 @Configuration bean 覆盖 @FeignClient 进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44265928/

相关文章:

java - 添加到 dependencyManagement 时,SpringBoot 不运行单元测试

java - 使用java获取dxdiag结果

java - 在 Spring Boot 应用程序中将 mongo db 升级到 3.2

java - 无法使用java解析.conf文件

java - 休息 : Handling matrix style and template style parameter with same name in a request

Spring Controller 建议无法正确处理 CompletableFuture 异常完成

python-3.x - 如何为运行直到键盘中断并且不返回任何内容的类编写单元测试?

java - 如何使用新的 JUnit 4.11 功能,包括更改测试名称和设置执行顺序

java - 奇数节点总和与偶数节点总和的二叉树差异

java - Java中的继承到底发生了什么?