2 Replies Latest reply on Mar 9, 2012 12:37 PM by aogier

    Testing CDI beans with ELContext and ExpressionFactory

    aogier

      (this is a copy of my question on Stackoverflow)

       

      I want to test some CDI beans which use javax.el.ElContext andjavax.el.ExpressionFactory.

      Until now, here is how I test my CDI beans :


      @RunWith
      (Arquillian.class)
      public class MyCDIBeanTest {

         
      @Deployment
         
      public static JavaArchive createTestArchive() {
             
      return ShrinkWrap
                     
      .create(JavaArchive.class, "test.jar")
                     
      .addClasses(MyCDIBean.class)
                     
      .addAsManifestResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));
         
      }

         
      ...

      Here is my current pom.xml :

      <dependency>
         
      <groupId>junit</groupId>
         
      <artifactId>junit</artifactId>
         
      <version>4.10</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.arquillian.junit</groupId>
         
      <artifactId>arquillian-junit-container</artifactId>
         
      <version>1.0.0.CR6</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.arquillian.container</groupId>
         
      <artifactId>arquillian-container-test-spi</artifactId>
         
      <version>1.0.0.CR6</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.arquillian.container</groupId>
         
      <artifactId>arquillian-container-spi</artifactId>
         
      <version>1.0.0.CR6</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.arquillian.container</groupId>
         
      <artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
         
      <version>1.0.0.CR3</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.weld</groupId>
         
      <artifactId>weld-core</artifactId>
         
      <version>1.0.0.CR3</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.weld</groupId>
         
      <artifactId>weld-api</artifactId>
         
      <version>1.1.2.Final</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.jboss.weld</groupId>
         
      <artifactId>weld-spi</artifactId>
         
      <version>1.1.2.Final</version>
         
      <scope>test</scope>
      </dependency>
      <dependency>
         
      <groupId>org.slf4j</groupId>
         
      <artifactId>slf4j-simple</artifactId>
         
      <scope>test</scope>
      </dependency>

      The versions are in the parent pom and weld and sl4j versions are imported with

      <dependency>
         
      <groupId>org.jboss.weld</groupId>
         
      <artifactId>weld-core-bom</artifactId>
         
      <version>1.1.2.Final</version>
         
      <scope>import</scope>
         
      <type>pom</type>
      </dependency>

      My beans I want to test now use javax.el.ElContext andjavax.el.ExpressionFactory.

      They use Seam Solder to @Inject them.

      So I added .addPackage(org.jboss.solder.el.Expressions.class.getPackage()) toShrinkWrap.

      But now here is what I got :

      javax.el.ELException: Provider org.apache.el.ExpressionFactoryImpl not found
          at javax
      .el.FactoryFinder.newInstance(FactoryFinder.java:97)
          at javax
      .el.FactoryFinder.find(FactoryFinder.java:193)
          at javax
      .el.ExpressionFactory.newInstance(ExpressionFactory.java:185)
          at javax
      .el.ExpressionFactory.newInstance(ExpressionFactory.java:156)
          at org
      .jboss.solder.el.ExpressionFactoryProducer.createExpressionFactory(ExpressionFactoryProducer.java:35)

      Does anybody knows how could I do that better ? (or just working)


        • 1. Re: Testing CDI beans with ELContext and ExpressionFactory
          dan.j.allen

          I proposed an extension awhile ago with working sample code.

           

          https://community.jboss.org/message/525871

           

          All that remains is turning that code into an extension as Aslak suggests. If you can get it working, would you be willing to turn it into an extension. It will help you get a much deeper understanding of Arquillian.

          • 2. Re: Testing CDI beans with ELContext and ExpressionFactory
            aogier

            OK here is what I did (inspired by that question).

            First I deleted the .addPackage(Expressions.class.getPackage()).

            Then I added a dependency to Juel :

            <dependency>
               
            <!-- Used to simulate El expressions without Faces environment -->
               
            <groupId>de.odysseus.juel</groupId>
               
            <artifactId>juel-impl</artifactId>
               
            <version>2.2.4</version>
               
            <scope>test</scope>
            </dependency>

            Then in my test I added that code :

            /// Methods & variables for the elContext ///
            static SimpleContext elContext = new SimpleContext();
            static ExpressionFactory expressionFactory = new ExpressionFactoryImpl();

            @Produces @RequestScoped
            public static ELContext getElContext() {
               
            return elContext;
            }

            @Produces @RequestScoped
            public static ExpressionFactory getExpressionFactory() {
               
            return expressionFactory;
            }

            @Before
            public void reInitElContext() {
                elContext
            = new SimpleContext();
            }

            private void setElVariable(final String variableName, final Object variableValue) {
                setElVariable
            (variableName, variableValue, variableValue.getClass());
            }

            private void setElVariable(final String variableName, final Object variableValue, final Class<? extends Object> variableClass) {
                expressionFactory
            .createValueExpression(elContext, "#{"+variableName+"}", variableClass).setValue(elContext, variableValue);
            }

            private void setElNullVariable(final String variableName, final Class<?> variableClass) {
                setElVariable
            (variableName, null, variableClass);
            }

            /**
            * By default, set a null String variable
            * @param variableName
            */

            private void setElNullVariable(final String variableName) {
                setElNullVariable
            (variableName, String.class);
            }

            Now I can use setElVariable("variableName", "value") in my tests !