【问题标题】:Injection not working properly in Arquillian Tests - strange errors注入在 Arquillian 测试中无法正常工作 - 奇怪的错误
【发布时间】:2014-04-14 06:53:20
【问题描述】:

我对 Arquillian 测试和 CDI 注入有一个奇怪的问题:

这个 bean 在测试时工作得非常好:

@RequestScoped
public class Greeter {

    @Inject
    protected GreetingProvider greetingProvider;

    public String doGreeting(String greet) {
        System.out.println("Information: greetingProvider=" + greetingProvider);

        return String.format("%s, %s!", greetingProvider.getGreetingWord(), greet);
    }

}

唯一的例外是,在以下测试用例中,方法“testGreetingProviderInGreeterIsNotNull()”总是失败

@RunWith(Arquillian.class)
public class GreeterTest {

    @Deployment
    public static WebArchive createDeployment() {
        WebArchive deployment = ShrinkWrap.create(WebArchive.class)
                .addClass(Greeter.class)
                .addClass(GreetingProvider.class)
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") ;

        return deployment;
    }

    @Inject
    private Greeter greeter;

    @Test
    @InSequence(1)
    public void testGreeterIsInjectedProperly() {
        assertNotNull(greeter);
    }

    @Test
    @InSequence(2)
    public void getGreetingTest() {
        String name = "John";
        String expected = "Hello, " + name + "!";
        String actual = greeter.doGreeting(name);
        assertEquals(expected, actual);
    }

    @Test
    @InSequence(3)
    public void testGreetingProviderInGreeterIsNotNull() {
        assertNotNull(greeter.greetingProvider);
    }


}

我不明白为什么,如果字段 greetingProvider 为空,那么第二个测试方法也会失败。

我的错误是什么?

完整的源代码可在 GitHub 上获得: https://github.com/t3chris/ArquillianInjectionTests

【问题讨论】:

  • --什么是失败?--没关系,我可以克隆并运行它:)
  • 我没有进一步查看,但服务器抱怨找不到 beans.xml 文件。不过,我可以在你的测试中清楚地看到它。
  • 失败/问题:当我尝试通过来自测试类的引用 greeter.greetingProvider 访问 greetingProvider 时,此引用似乎为空。但这不可能,否则第二次测试将无法进行。由于 Greeter 中的注入工作正常,我假设有一个 beans.xml

标签: cdi jboss-eap-6 jboss-arquillian


【解决方案1】:

我相信,但不是 100% 肯定,这是因为您在 src/test/resources 文件夹中缺少一个 arquillian.xml,它应该强制使用 Servlet 3 的默认协议。默认情况下,在 AS7/EAP6 中,协议是他们的 JMX协议。当您使用他们的 JMX 协议时,RequestScope 对交互无效。

您的 arquillian.xml 应该如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.org/schema/arquillian"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

    <defaultProtocol type="Servlet 3.0" />
</arquillian>

【讨论】:

  • 刚刚尝试过,但不幸的是它没有任何区别。我还通过切换 deploymentExportPath 设置验证了 arquillian.xml 是否位于正确的位置。我认为@RequestScoped 受到尊重,因为实际注入到 Greeter 中是有效的——它只是从测试中看不到......
  • 哦,对不起。当您尝试访问该变量时,greetingProvider 为 null 的原因是,当您尝试对其执行某些操作时,CDI 会在运行时为其分配一个代理。但是,当您在该 bean 之外直接使用代理时,您无法访问该 bean 的字段。如果您使用吸气剂,它实际上应该可以工作,但根据 CDI 规范,无论哪种方式,您都不应该访问这些字段。
  • 抱歉,按 Enter 太早了。我问的原因是因为我想用模拟实现替换没有接口(@Localbean)的 EJB。因此,我只想覆盖此参考。在 Arquillian 中是否有其他方法可以在没有接口的情况下模拟 EJB 或 Web 服务?
  • 很好的模拟违背了 Arquillian 的目的 :) 尝试使用包级别设置器来设置值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
相关资源
最近更新 更多