4 Replies Latest reply on Jan 7, 2009 2:45 PM by jan.kadlec

    JSFUnit Seam and conversation scope

    jan.kadlec

      Hi,

      I have problem accessing conversation scoped beans in JSFUnit with Seam-tested application. There is an example "jboss-jsfunit-examples-seam-booking". In ConversationScopeTest.java there is assertion against "#{hotel}" bean via EL - and it pass

      BUT!

      this bean is in fact "hotel.component" in application context and not bean named "hotel" outjected in tested action in conversation scope. Why do I think so? When I renamed domain bean Hotel from @Name("hotel") to @Name("hotelDomain") there were assertion failure accessing "conversation" bean hotel.

      Is there any examples with JSFUnit and Seam accessing conversation scoped beans?

      Thanx a lot

      regard

      Jan Kadlec

        • 1. Re: JSFUnit Seam and conversation scope
          ssilvert

          I think there is a problem with that test, but it is not returning "hotel.component" from application scope.

          I added this code to the test:

          Map appMap = server.getFacesContext().getExternalContext().getApplicationMap();
           System.out.println("-----------------------------");
           Object hotel = server.getManagedBeanValue("#{hotel}");
           System.out.println("hotel=" + hotel);
           System.out.println("hotel.getClass().getName()=" + hotel.getClass().getName());
           Object hotelComponent = appMap.get("hotel.component");
           System.out.println("hotelComponent=" + hotelComponent);
           System.out.println("hotelComponent.getClass().getName()=" + hotelComponent.getClass().getName() );
           System.out.println("same object? " + (hotel == hotelComponent));
           System.out.println("-----------------------------");


          The result:
          10:40:58,515 INFO [STDOUT] -----------------------------
          10:40:58,517 INFO [STDOUT] hotel=Hotel(null,null,null,null)
          10:40:58,519 INFO [STDOUT] hotel.getClass().getName()=org.jboss.seam.example.bo
          oking.Hotel
          10:40:58,523 INFO [STDOUT] hotelComponent=Component(hotel)
          10:40:58,525 INFO [STDOUT] hotelComponent.getClass().getName()=org.jboss.seam.C
          omponent
          10:40:58,528 INFO [STDOUT] same object? false
          10:40:58,530 INFO [STDOUT] -----------------------------


          What is unexpected is that getManagedBeanValue("#{hotel}") would return a newly-initialized Hotel object. The uninitialized Hotel object might be explained by https://jira.jboss.org/jira/browse/JSFUNIT-164. So that would mean the test passes, but in an unexpected way.

          I'll have to look into this further and double-check to make sure I have a Seam Conversation scope test that really does what was intended.

          Stan

          • 2. Re: JSFUnit Seam and conversation scope
            ssilvert

            Jan,

            I just wanted to let you know that I agree conversation scope is broken. It always returns a shallow copy. I'm working on the problem right now. Thanks for your patience.

            Stan

            • 3. Re: JSFUnit Seam and conversation scope
              ssilvert

              This is now fixed. I'm uploading a snapshot that you can try out.

              See http://snapshots.jboss.org/maven2/org/jboss/jsfunit/jboss-jsfunit-core/1.0.0.GA-SNAPSHOT/

              I fixed this by caching all conversation scope objects in a Map stored the HttpSession. JSFUnit manages this automatically. Conversation scope objects are stored after calls to Lifecycle.execute() and Lifecycle.render(). These conversation scope objects are held in the map as long as the JSFSession is active. When a new JSFSession is created then the conversation scope Map is cleared.

              This means that if a conversation ends then the old conversation scope objects will still be available in the cache as long as the same JSFSession is active.

              To implement this, a new LifecycleFactory and Lifecycle are installed for JSFUnit. Also, a VariableResolver is created that knows how to get things from the special conversation scope Map.

              To access objects in conversation scope, you should include "seamconversation" as part of the EL expression passed to getManagedBeanValue().

              Example test fragment for Seam booking demo:

              assertEquals("/hotel.xhtml", server.getCurrentViewID());
              
               client.click("hotel:bookHotel");
              
               Hotel hotel = (Hotel)server.getManagedBeanValue("#{seamconversation.hotel}");
               assertNotNull(hotel);
               assertEquals("Hilton Diagonal Mar", hotel.getName());


              Stan

              • 4. Re: JSFUnit Seam and conversation scope
                jan.kadlec

                Realy!!

                Wonderfull, Amazing, GREAT!!!

                Thank you very much, realy.

                Jan