【发布时间】:2021-11-09 10:26:17
【问题描述】:
我有一个测试用例,其中基于布尔属性,我们决定在应用程序启动时创建 2 个 Spring Bean 中的哪一个。
为简单起见,我们称它们为ProfileServiceA 和ProfileServiceB。
当布尔属性设置为false(默认值)时,它会创建ProfileServiceA,当它是true 时,它会创建ProfileServiceB。
这是在使用@Configuration 注释的配置类中完成的。
我的测试非常简单,我想验证当我们的应用程序基于该属性启动时,Spring 上下文中加载了哪一个 Bean。
对于这些 Bean 中的每一个,当我们创建它们时,构造函数会获取多个对象以便实例化。
我使用@MockBean 注释的大多数对象,因为它们只在构造函数中被指向,就像我们通常使用依赖注入所做的那样,这对我来说不是问题。
这些属性之一不仅在构造函数中被指出,而且实际上被用于构建其中一个字段。
在 ProfileService 的构造函数中,我们这样做:
this.url = securityProperties.getProfile().getProtocol() + "://" + securityProperties.getProfile().getHost() + ":" + securityProperties.getProfile().getPort() + "/" + securityProperties.getProfile().getEndpoint();
SecurityProperties 类具有内部静态类 Profile,因此当应用程序上下文开始加载并且此 Bean 在构造函数中被实例化时(甚至在使用 @987654332 注释的方法之前@) 我在 NullPointerException 上失败,因为对象 Profile 仍然为空(SecurityProperties 不是因为它被 @MockBean 注释)。
SecurityProperties 及其内部静态类 Profile 未定义为 Bean,但我仍然尝试将测试类中的 Profile 对象也设置为 @MockBean 或 @Mock 但这并没有解决问题。
我想我可能需要将“真实”对象注入到上下文中,但我找不到关于如何将带有模拟对象的“真实”对象注入到 Autowired Spring Bean 的 wiki/docs。
SecurityProperties 不是 Spring Bean,而是常规数据对象 (POJO)。
【问题讨论】:
-
所以你不使用依赖注入获取ProfileService而是自己调用构造函数?是否可以在服务上使用@Profile("myProfile") 注释来自动创建具有自动装配依赖关系的所需服务?
-
我确实使用依赖注入。在测试类中,ProfileService 用“Autowired”注释。应该注入到该 Bean 的构造函数中的字段都用“MockBean”注释(如 SecurityProperties 类)。它们在构造函数中不为空,只有 Profile 类,它是 SecurityProperties 内部的内部静态类。
标签: java spring testing mocking