injecting mock beans into spring context for testi

2019-02-03 15:20发布

问题:

I know similar questions have been asked, e.g. here, but having done a search, I've come upon a solution I'm much happier with here

My only problem however, is that I'm not sure how to implement this solution.

What I want to be able to do is via the HotswappableTargetSource override the bean definitions of select beans in my application context with my test versions and then run the test.

Then for each test case I'd like to specify which beans I want to be hot swappable and then each test must be able to create its own mock versions and swap those in, and be able to swap back again.

I am able to get the Application Context the test is running with but what I don't know is how to configure a bean to be hot swappable. I know how to do it when configuring beans with xml but I don't want to go back to using xml to configure beans.

回答1:

UPDATE: There's a library that does it!

https://bitbucket.org/kubek2k/springockito/wiki/springockito-annotations

The solution is as follows:

You will need to change the spring context of your application to proxy the bean you want to swap:

<bean id="beanSwappable" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource" ref="beanSwap" />
</bean>

<bean id="beanSwap" class="org.springframework.aop.target.HotSwappableTargetSource">
    <constructor-arg ref="beanToSwap" />
</bean>
  • beanSwap is the proxy onto this beanSwap.
  • beanSwappable is the bean which you reference when you want to swap the bean
  • beanToSwap is the default implementation of the bean

Thus a change to the system under test is necessary.

And in your test the code will look like:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "test.xml", "spring.xml" })
public class Test {

    @Resource(name="beanSwappable")
    Bean b;

    @Resource(name = "beanSwap")
    HotSwappableTargetSource beanSwap;

    public void swap() {
        Bean b = << create mock version >>
        beanSwap.swap(b);
        // run test code which

    }
}