Results 1 to 7 of 7

Thread: mock testing with spring managed beans

  1. #1
    Join Date
    Apr 2005
    Posts
    18

    Default mock testing with spring managed beans

    Hi,

    we have decorated our Spring managed beans with advices via the org.springframework.aop.framework.autoproxy.BeanNa meAutoProxyCreator using beanNames, as in:

    <bean id="proxyCreator" class="org.springframework.aop.framework.autoproxy .BeanNameAutoProxyCreator">
    <property name="beanNames">
    <list>
    <value>*Bean</value>
    </list>
    </property>
    <property name="interceptorNames">
    <list>
    <value>MyAdvice</value>
    </list>
    </property>
    </bean>

    <bean id="myBean" class="MyBeanDefault" />

    so if I get "myBean" from the applicationContext the reference will be that of a proxy due to the decorating advice. For mock testing purposes what I'd like to do is get a reference to MyBeanDefault, ie without the proxy, from the applicationContext - any ideas, outside of re-declaring the bean with a different name?


    thanks

    drc

  2. #2
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Lightbulb Some caffeine-induced ideas...

    That's the great thing about this forum - you learn about a new part of the framework every day!

    Anyway, one idea would be to use a separate bean definition file just for your test cases. This test-only file could either leave out the BeanNameAutoProxyCreator completely, or (if that wasn't feasible) change its "beanNames" property not to include the beans you didn't want proxied.

    Another idea is to change your existing bean definition file to read the names of the to-be-decorated beans from a system property. In production you would set this property to its current "*Bean" value, whereas in your tests you could set it to whatever you wanted.

    I've had another idea (on a roll, just had my coffee!). If your test case is application context aware (or can be made so), and if the advice is only applied at the time of getting the target bean (as opposed to when the app context loads), which may be enforceable via the lazy-init parameter, then your test case could (1) set the proxy creator's "beanNames" not to include "myBean", then (2) get "myBean", which would therefore not be proxied, then (3) set the proxy creator's "beanNames" back to its normal value.

    All of the above begs the question of what you mean by "mock" though. You didn't explain exactly what you want to mock, but if you want to mock "myBean", why not use EasyMock or a similar mock-generating tool?
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  3. #3
    Join Date
    Apr 2005
    Posts
    18

    Default

    We want to mock out (using jmock) the collaborators of our spring managed beans, so MyBean is the class that will have its collaborators mocked out, ie dao's etc. Given that our advices open/close transactions & do other things I dont want these to be part of the mock test - hence I only want the MyBean instance returned from the spring factory without the proxys. So the test case is application context aware.

    As for some of your suggestions:
    - I could redefine myBean in applicationContext*.xml - but then I'd have to maintain this definition as well - so this isnt an option
    - The system properties - not really sure how this would work
    - I'II look into the idea of lazy-init & changing the proxy-creators beans to not include *Bean


    Go Sydney Swans...


    drc

  4. #4
    Join Date
    Oct 2004
    Location
    Fareham, England
    Posts
    313

    Default

    Hi drc

    For unit testing, why not just use a plain vanilla JUnit test in conjunction with JMock? You can totally leave out the Spring container in that case; this is certainly the approach that I and a number of the other Spring dev team use. To wit...

    Code:
    public final class FooTests extends TestCase {
    
        public void testBar() {
            Foo foo = new Foo();
            
            // inject JMock-based collaborators into the Foo instance
            
            // test!
        }
    
        public void testBaz() {
            Foo foo = new Foo();
            
            // inject JMock-based collaborators into the Foo instance
            
            // test!
        }
    }
    Cheers
    Rick

  5. #5
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Cool +1

    I was just about to ask drc the same thing!
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  6. #6
    Join Date
    Apr 2005
    Posts
    18

    Default

    Rick & Andews,

    the reason why I want to use the spring container in the test is that getting the beans from the spring container will result in all of the collaborators being injected into the spring managed bean. There are a couple of benefits I see to this, rather doing a new on the bean as suggested:
    1) I dont have to new all of the collaborators and then physically inject them into the bean in the test
    2) when the bean under test changes, eg a new collaborator, then I dont have to go back to my test and inject it in, as Spring will have already injected it in for me

    So I think it results in a bit less code in the test and a bit less maintenance over time.

    let me know what u think?

    thanks.

  7. #7
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    In this case you'll have to use either a different proxying technique (so you'll end up with two beans definitions - one of the original bean and one of the proxied bean) or you can set exposeProxy to true on BeanNameAutoProxyCreator.
    See the javadoc for ProxyConfig for more info.
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •