【问题标题】:spring boot - integration test autowired interface no such bean foundspring boot - 集成测试自动装配接口没有找到这样的bean
【发布时间】:2021-07-17 07:54:20
【问题描述】:

我有一个 spring-boot 应用程序,现在需要支持多个对象存储,并根据环境有选择地使用所需的存储。基本上我所做的是创建一个接口,然后每个商店存储库都实现。

我已经简化了示例的代码。 我根据确定环境的弹簧配置文件为每种商店类型创建了 2 个 bean:

  @Profile("env1")
  @Bean
  public store1Sdk buildClientStore1() {
     return new store1sdk();
  }

  @Profile("env2")
  @Bean
  public store2Sdk buildClientStore2() {
     return new store2sdk();
  }

在服务层中,我自动装配了接口,然后在存储库中,我使用@Profile 来指定要使用的接口实例。

public interface ObjectStore {
  String download(String fileObjectKey);
  ...
}

@Service
public class ObjectHandlerService {

  @Autowired
  private ObjectStore objectStore;

  public String getObject(String fileObjectKey) {
    return objectStore.download(fileObjectKey);
  }
  ...
}

@Repository
@Profile("env1")
public class Store1Repository implements ObjectStore {
  @Autowired
  private Store1Sdk store1client;

  public String download(String fileObjectKey) {
    return store1client.getObject(storeName, fileObjectKey);
  }
}

当我使用配置的“env”启动应用程序时,它实际上按预期运行。但是,在运行测试时,我得到“没有 ObjectStore 类型的合格 bean。预计至少有 1 个符合自动装配候选资格的 bean。”

@ExtendWith({ SpringExtension.class })
@SpringBootTest(classes = Application.class)
@ActiveProfiles("env1,test")
public class ComposerServiceTest {
  @Autowired
  private ObjectHandlerService service;

  @Test
  void download_success() {
    String response = service.getObject("testKey");
    ...
  }
}

正如测试类的@ActiveProfile 中所述,还有一些其他环境,例如开发,测试,产品。我尝试过使用组件扫描,在同一个包中包含 impl 和 interface 等,但没有成功。我觉得我在测试设置中遗漏了一些明显的东西。但可能与我的整体应用程序配置有关吗?我使用该解决方案的主要目的是避免出现冗长的内容

    if (store1Sdk != null) {
      store1Sdk.download(fileObjectKey);
    }
    if (store2Sdk != null) {
      store2Sdk.download(fileObjectKey);
    }

【问题讨论】:

    标签: java spring-boot junit5 spring-boot-test


    【解决方案1】:

    试试@ActiveProfiles({"env1", "test"})

    使用@ActiveProfiles 激活多个配置文件并将配置文件指定为数组。

    【讨论】:

      【解决方案2】:

      这个问题因为Store1Repository 使用@Profile("env1"),当你使用@test 时,这个类不会被调用。尝试删除@Profile("env1") of Store1Repository

      如果你使用@test,两个store1Sdk/store2Sdk都不要实例化,尝试添加默认instanse.eg

      @Bean    
      public store2Sdk buildClientStoreDefault() {
          return new store2sdk();
      }
      

      【讨论】:

      • 如果您从存储库实现中删除配置文件注释,您会不会遇到相反的问题,即尝试实例化 2 个 ObjectStore 实例?
      • 如果你使用@test,store1Sdk/store2Sdk都没有实例化,尝试添加默认实例化。例如:
      猜你喜欢
      • 2016-10-10
      • 1970-01-01
      • 2020-07-03
      • 2021-01-24
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      相关资源
      最近更新 更多