首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arquillian使用CDI测试JSF - CDI范围问题

Arquillian使用CDI测试JSF - CDI范围问题
EN

Stack Overflow用户
提问于 2017-01-27 19:53:21
回答 2查看 438关注 0票数 1

我们正在将我们的JavaEE应用程序从WebLogic10.3.6迁移到WebLogic12.2.1.2。作为迁移的一部分,我们将JSF托管bean更改为使用CDI注释,而不是标准的JSF注释。@ManagedBean@Namedjavax.faces.bean.ViewScopedjavax.faces.view.ViewScoped。事实证明,这是成功的,只是出现了一些小问题。然而,我在尝试运行我们的测试时遇到了一个很大的问题。测试失败,并显示以下错误:

代码语言:javascript
复制
WebBeans context with scope type annotation @ViewScoped does not exist within current thread

我尝试了多个不同的容器(嵌入式和远程),但仍然收到相同的错误。任何帮助都将不胜感激。

我正在使用具有以下pom.xml依赖项的Arquillian:

代码语言:javascript
复制
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.arquillian</groupId>
            <artifactId>arquillian-bom</artifactId>
            <version>1.1.12.Final</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>


<dependencies>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.tomee</groupId>
        <artifactId>arquillian-openejb-embedded</artifactId>
        <version>7.0.2</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.jboss.arquillian.junit</groupId>
        <artifactId>arquillian-junit-container</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>javax.faces-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>6.0.13</version>
    </dependency>

    <dependency>
        <groupId>org.primefaces.themes</groupId>
        <artifactId>all-themes</artifactId>
        <version>1.0.10</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

</dependencies>

BackingBean:

代码语言:javascript
复制
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;

@Named
@ViewScoped
public class AnotherBean implements Serializable {

    public String doTest()
    {
        System.out.println("test");
        return "test";
    }
}

TestBean

代码语言:javascript
复制
@RunWith(Arquillian.class)
public class TestAgain  {

    @Deployment
    public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class, "test.jar")
                .addClass(AnotherBean.class)
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Inject
    AnotherBean anotherBean;

    @Test
    public void doTest()
    {
        Assert.assertEquals(anotherBean.doTest(), "test");
        anotherBean.doTest();
    }
}

更新

如果我将@Deployment更改为:

代码语言:javascript
复制
@Deployment
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class, "test.jar")
                .addClass(AnotherBean.class)
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
    }

我得到了:

代码语言:javascript
复制
javax.enterprise.inject.UnsatisfiedResolutionException: Api type [AnotherBean] is not found with the qualifiers 
Qualifiers: [@javax.enterprise.inject.Default()]
for injection into Field Injection Point, field name :  anotherBean, Bean Owner : [null]
EN

回答 2

Stack Overflow用户

发布于 2017-02-10 14:51:08

我们在测试@ViewScoped bean时遇到了类似的困难。我们通过在自己的测试文件中创建带有注入的bean解决了这个问题。

Bean实例本身是在测试中创建的,然后使用反射将所有依赖项插入其中。这适用于bean、entitymanger等

代码语言:javascript
复制
@RunWith(Arquillian.class)
public class ViewControllerTest {
@Inject private OtherBean otherBean;

private ViewController viewController;


@Deployment
public static WebArchive createDeployment() {
  return WebArchiveFactory.getDefaultWebarchArchive();
}

@Before
public void setup() throws Exception {
  viewController = new ViewController();
  TestHelper.setFacesContext(); // provide FacesContextMock
  TestHelper.inject(viewController, "otherBean", otherBean);
}
}

TestHelper看起来像这样

代码语言:javascript
复制
public class TestHelper {

public static void inject(Object bean, 
                          String fieldName, 
                          Object fieldValue) throws Exception {
  if (null == bean) {
    throw new IllegalArgumentException("Bean must not be null");
  }
  Field field;
  try {
    field = bean.getClass().getDeclaredField(fieldName);
  } catch (NoSuchFieldException e) {
    log.log(Level.SEVERE, "Could not find field for injection: " + fieldName);
    throw e;
  }
  field.setAccessible(true);
  field.set(bean, fieldValue);
}
}
票数 0
EN

Stack Overflow用户

发布于 2017-02-15 16:44:02

最后,我不得不用一个很好的老式技巧来解决这个问题。我找到了org.apache.webbeans.container.BeanManagerImpl的源代码,也就是原始WebBeans context with scope type annotation @ViewScoped does not exist within current thread的来源。我在我的测试源码中创建了这个类,然后我做了一些更改来解决这个问题。

归根结底,对于我的测试,我并不关心范围。我正在测试这些方法是否运行并返回正确的逻辑/数据。因此,在类中,它检查bean所在的作用域类型,并抛出异常。我只是简单地检查了它是否在Viewscoped中,如果是,则将其更改为Dependent。这样我的测试就可以正常工作了。

这不是最好的解决方案,但它是有效的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41893394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档