1 Reply Latest reply on Nov 27, 2012 12:36 AM by vineet.reynolds

    how to access sessionscoped bean across tests

    cuneyt

      Have been struggling with a test case where a service is dependent on having a session scoped bean being in the session fails;

      The class producing @SessionScoped User:

      public class LoginService { 

           private User user; 

           public void login(String name) {

                if ("userA".equals(name)) {

                     user = new User(name, "permissionA");

                } else if ("userB".equals(name)) {

                     user = new User(name, "permissionB");

                } else {

                     user = new User("anonymous", "");

                }

          } 

           @Producer

           @LoggedIn

           @SessionScoped

           public User getLoggedIn() {

                return this.user;

           }

      }

      The service using the @LoggedIn User:

      public class MediaService {

           @Inject

           @LoggedIn

           private User user; 

          

           public void updateImage(){

                if("permissionA".equals(user.getPermission())){

                     System.out.println("user can update image");

                }

                else {

                     System.out.println("user can not update image");

                }

           }

      }

      And the test:

          @RunWith(Arquillian.class)

           public class ServiceTest { 

                @Deployment public static WebArchive deployment() {

                     return ShrinkWrap .create(WebArchive.class, "test.war")

                     .addClass(LoggedIn.class)

                     .addClass(LoginService.class)

                     .addClass(MediaService.class)

                     .addClass(User.class)

                     .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");

                } 

                @Inject private LoginService lservice; 

                @Inject private MediaService mservice; 


                @Test

                public void testLogin() {

                     lservice.login("userA");

                } 

                @Test

                public void testUpdateImage(){

                     mservice.updateImage();

                }

      }

      Testing with the arquillian remote container, first test (testLogin) passes and the testUpdateImage fails with null User in session.

      WELD-000052 Cannot return null from a non-dependent producer method: 

      [method] @Produces @LoggedIn @SessionScoped public org.arg.service.LoginService.getLoggedIn()

      Thanks

        • 1. Re: how to access sessionscoped bean across tests
          vineet.reynolds

          I think you need to relook at the scope of your services. While your producer method is @SessionScoped, the enclosing LoginService instance is not, and therefore at runtime, the reference to the user field is null - the original LoginService instance would have been disposed of and new one would have been created.

           

          After you solve the problem surrounding your scope, you may still encounter this problem since the Arquillian test enricher perform non-contextual CDI injection for the test class instance. In that event, you're better off using a @Before method to invoke LoginService.login(..) ensuring that the User is available in the subsequent methods invoked in an individual test.