如何向DeltaSpike实例化的类中注入@Resource资源?
首先直接给你明确答案:是的,DeltaSpike 作为增强型 CDI 容器,完全支持通过 @Resource 注解注入资源。不过在你的测试场景(结合 Mockito、无需启动 JBoss EAP)下,需要注意一些配置细节和实践要点,下面给你详细拆解:
1. 核心支持逻辑
DeltaSpike 是基于 CDI 规范的扩展框架,天然兼容 Java EE 的资源注入规范——包括 @Resource 注解。不管是注入 JNDI 绑定的资源、WebService 代理,还是其他容器管理的资源,只要你的类被 DeltaSpike 的 CDI 容器管理(即成为 CDI Bean),就可以正常使用 @Resource 完成注入。
2. 测试场景下的配置前提
要让 DeltaSpike 实例化你的 XyConsumer 并处理 @Resource 注入,首先得确保测试类正确启用 DeltaSpike 的测试容器:
- 如果你用 JUnit 4,需要在测试类上添加
@RunWith(CdiTestRunner.class) - 如果你用 JUnit 5,需要添加
@ExtendWith(CdiExtension.class)
这一步是让 DeltaSpike 接管测试环境的 CDI 上下文,才能识别和处理 @Inject、@Resource 这类注解。
3. 针对内部框架生成的 XyConsumer 的处理
因为你的 XyConsumer 是内部框架生成的,需要确认它是否被标记为 CDI Bean(比如带有 @ApplicationScoped、@RequestScoped 等 scope 注解,或者被内部框架通过其他方式注册到 CDI 容器):
- 如果已经是 CDI Bean:直接在测试类中用
@Inject获取实例即可,DeltaSpike 会自动处理其中的@Resource注入。 - 如果不是 CDI Bean:可以通过 DeltaSpike 的
BeanProvider手动获取实例,或者在测试中创建一个@Alternative的子类并标记为 CDI Bean,让 DeltaSpike 管理它:@Alternative @ApplicationScoped public class TestableXyConsumer extends XyConsumer { // 无需额外代码,直接继承父类逻辑即可 }
4. 结合 Mockito 模拟 @Resource 资源
你的场景是测试 WebService 消费者,肯定需要 Mock 掉实际的 WebService 资源(避免依赖外部服务)。这里有两种高效的实践方案:
方案一:用 DeltaSpike Mock 扩展直接 Mock 资源
DeltaSpike 自带 Mock 支持,配合 @Mock 注解可以直接替换 @Resource 注入的实例:
@RunWith(CdiTestRunner.class) public class XyConsumerTest { @Inject private XyConsumer xyConsumer; // 用 @Mock 标记要注入的资源,DeltaSpike 会自动替换实际实例 @Mock @Resource(lookup = "java:comp/env/xyWebService") private XyWebService mockWebService; @Test public void testWebServiceInvocation() { // 配置 Mock 行为 Mockito.when(mockWebService.processRequest(Mockito.anyString())) .thenReturn("Mocked Response"); // 调用消费者方法 String result = xyConsumer.callWebService("test request"); // 验证结果和 Mock 调用 Assert.assertEquals("Mocked Response", result); Mockito.verify(mockWebService).processRequest("test request"); } }
方案二:手动绑定 JNDI 资源到 Mock 实例
如果你的 @Resource 是通过 JNDI lookup 定位资源,也可以在测试初始化时手动将 Mock 实例绑定到对应的 JNDI 名称:
@Before public void setupJndiMock() throws NamingException { // 模拟 JNDI 上下文,绑定 Mock 实例 InitialContext initialContext = new InitialContext(); initialContext.bind("java:comp/env/xyWebService", mockWebService); }
不过这种方式相对繁琐,更推荐用 DeltaSpike 的 Mock 扩展来简化操作。
5. 注意事项
- 确保 DeltaSpike 的测试依赖已经正确引入到你的构建文件中,比如
deltaspike-test-control-api和deltaspike-test-control-impl。 - 如果内部框架生成的
XyConsumer中有复杂的资源依赖,可能需要用@Specializes或者@Alternative来替换其中的部分组件,保证测试环境的独立性。
内容的提问来源于stack exchange,提问作者Alex Schmidt

