Announcement Announcement Module
Collapse
No announcement yet.
Testing Beans of Request/Session Scope Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Testing Beans of Request/Session Scope

    Hello,

    Using a login screen, I have implemented authorization/authentication in an application. The login-attempt data (like username) is stored in the 'LoginRequest' bean having scope 'request'. The user's information is stored in the 'WebSession' bean having scope 'session'.

    I am now trying to test this authorization/authentication functionality with JUnit tests (using Ant) and AbstractDependencyInjectionSpringContextTests.

    I have searched the web for examples of JUnit testing beans with scope request/session, but I really haven't found any.

    My impression is that the only way to simulate this is to call the 'setDirty()' function, but I would like something more elegant. Ideally, I would like to be able to simulate 2 or more requests per session.

    For instance, does AbstractDependencyInjectionSpringContextTests have something like open/closeSession and open/closeRequest?

    Any help is appreciated.

    Thanks,

    Gary

  • #2
    I don't bother about scopes in my tests. I inject scoped proxies in to be deployed code and actual beans in tests.

    Jörg

    Comment


    • #3
      Hi Jörg,

      Thank you for the quick response.

      I must admit that I only have a vague idea of what you mean when you say 'inject scoped proxies', especially in the context of JUnit and AbstractDependencyInjectionSpringContextTests.

      My understanding of the 'request' scope is that the actual bean is tied to a thread. Therefore, if a single-threaded unit test requests a 'request' scope bean more than once, the BeanFactory will return the same bean.

      I did try to use dependency injection for the 'request' scope bean in my JUnit test, but I believe that it resulted in an error.

      If possible, please provide me a JUnit (AbstractDependencyInjectionSpringContextTests or other Spring superclass) example of 'injecting scoped proxies'. Will CGLib be required?

      Any help is appreciated.

      Thanks,

      Gary

      Comment


      • #4
        Would you mind to post the setup for your WebSession just to be sure we're talking about the same? I guess we are talking about a bean managed by Spring and an attribute in the XML config scope="session".

        Jörg

        Comment


        • #5
          JUnit with Request/Session Beans

          Hi Jörg,

          Yes, WebSession has scope="session". Likewise, there are other beans with scope="request" (like userAccessor).

          It seems like AbstractDependencyInjectionSpringContextTests does not behave as if it were in a web context, but prefers to deal with singletons/prototypes instead.

          When I add get/setUserAccessor to the subclass (TestUserAccessor) of AbstractDependencyInjectionSpringContextTests, the JUnit test generates the following exception.

          java.lang.IllegalStateException: No Scope registered for scope 'request' at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:282) at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:160) at com.cisco.paws.security.TestUserAccessor.testSimpl e(TestUserAccessor.java:36) at org.springframework.test.ConditionalTestCase.runBa re(ConditionalTestCase.java:69)

          You have been very willing to help. If this is taking too much time, I might be able to (eventually) figure it out on my own.

          Take Care,

          Gary

          Comment


          • #6
            AbstractDependencyInjectionSpringContextTests cannot understand request/session scope

            I have analyzed the source code (2.0.6 and 2.1 M2). It appears that AbstractDependencyInjectionSpringContextTests does not have the capability to handle beans of scope "request" and "scope".

            There is no mention of the "request" and "session" (including quotes) until the WebApplicationContext (interface). There is no mention of BeanFactory's "registerScope" until AbstractRefreshableWebApplicationContext, GenericWebApplicationContext, StaticWebApplicationContext, AbstractRefreshablePortletApplicationContext, and StaticPortletApplicationContext (classes).

            Neither of these can be found in the heirarchy of AbstractDependencyInjectionSpringContextTests.

            It appears that Chapter 8 (Testing) of the Spring Reference makes no mention of this.

            There may be a way to test "request" and "session" scoped beans, but AbstractDependencyInjectionSpringContextTests provides no readilly usable way of doing so.

            Comment


            • #7
              Originally posted by garysteinmetz View Post
              There may be a way to test "request" and "session" scoped beans, but AbstractDependencyInjectionSpringContextTests provides no readilly usable way of doing so.
              I couldn't let that one go by - nothing like a challenge. N.B. I would agree with Joerg in general that it is simpler to construct a proxy if necessary. And this is not really a unit test (more an integration test). But it certainly isn't all that difficult to set up the scope for a test case:

              Code:
              public class ScopeTests extends AbstractDependencyInjectionSpringContextTests {
              
              	private ServletRequestAttributes attributes;
              
              	private TestBean bean;
              
              	public void setBean(TestBean bean) {
              		this.bean = bean;
              	}
              
              	@Override
              	protected String[] getConfigLocations() {
              		// scope.xml has one bean with scope="session"
              		return new String[] { "scope.xml" };
              	}
              
              	private void setUpRequest(ConfigurableApplicationContext context) {
              		context.getBeanFactory().registerScope("session", new SessionScope());
              		MockHttpServletRequest request = new MockHttpServletRequest();
              		attributes = new ServletRequestAttributes(request);
              		RequestContextHolder.setRequestAttributes(attributes);
              	}
              	
              	@Override
              	protected void prepareTestInstance() throws Exception {
              		setUpRequest(applicationContext);
              		super.prepareTestInstance();
              	}
              
              	public void testInjection() throws Exception {
              		assertNotNull(bean);
              		assertEquals("foo", bean.getName());
              	}
              
              	public void testAgain() throws Exception {
              		assertNotNull(bean);
              		assertEquals("foo", bean.getName());
              	}
              }
              Last edited by Dave Syer; Jun 20th, 2007, 02:20 AM. Reason: removed onSetUp/TearDown (not needed)

              Comment


              • #8
                Originally posted by garysteinmetz View Post
                It seems like AbstractDependencyInjectionSpringContextTests does not behave as if it were in a web context, but prefers to deal with singletons/prototypes instead.
                Yes, that's what I'd expect. Though I did not know that it is so easy to add.

                What I had in mind was to not test with those proxies at all. Let me create an example. If you have a service that works with a session-scoped object as field you'd inject a proxy to keep the service stateless:

                Code:
                public class Service {
                
                  private Object object;
                
                  public Service(Object object) {
                    // in a web environment it's a session-scoped proxy
                    this.object = object;
                  }
                
                  public void serviceMethod() {
                    // do some work with the object
                  }
                
                }
                Now when you test this Service you don't inject a session-scoped proxy but only a plain object.

                Hope this gives you the idea.

                Jörg

                Comment

                Working...
                X