开发者

Injecting mock into Spring container without xml for testing

Currently I have my spring application wired up using @Autowired, @Component, @Resource etc. Now I want to write a test that requires the mocking of specific objects in the system but retaining the real production wiring of the remaining objects.

Let's say the root object being tested is called Foo. Deeper down the dependency chain, Foo depends on Bar. Currently to mock out this object, I have created a test-applicationContext.xml that has just the single bean entry of:

<bean id="bar" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="com.package.Bar" /> 
</bean>

The test-applicationContext.xml is declared in the @ContextConfiguration annotation and therefore Foo will ultimately depend on the mocked Bar object.

Is it possible to get the same result without having to have this test-applicationContext.xml? i.e. do the same but progrmatically?

So in pseudo code, I was wondering if I could have something like:

开发者_运维知识库
public class MyTest {

    @Test
    public void simple() {
        // create mock Bar object
        // register mock Bar object in container
        // resolve Foo object with all its dependencies but use the mock Bar object instead of the real one
        // set some expectations on the Bar object
        // call some method on Foo
    }
}


You have to avoid starting the Spring context in your unit tests. Use the Spring context only in tests that check properties injection and other Spring features. Then, you will be able to create programatically mock objects.

Althought, it can be done with something like:

  BeanDefinitionRegistry registry = ((BeanDefinitionRegistry )factory);

  GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
  beanDefinition.setBeanClass(MyBeanClass.class);
  beanDefinition.setLazyInit(false);
  beanDefinition.setAbstract(false);
  beanDefinition.setAutowireCandidate(true);
  beanDefinition.setScope("session");

  registry.registerBeanDefinition("dynamicBean",beanDefinition);

Just inject your BeanFactory in your JUnit to get the factory


One way to do it:

  1. In your test context, component-scan the bare minimum.

  2. @Autowire the dependencies of Bar into your test class.

In your SetUp:

  1. Manually new Bar()

  2. Create mock of Foo

  3. Set properties of new Bar including the @Autowired (first #2) and mock (second #2).


I had a very similar problem and used https://bitbucket.org/kubek2k/springockito/wiki/Home that was really heplful to me.

In your case you can use if you want total mock then use @ReplaceWithMock or you can use @WrapWithSpy which will do partial mock and only you can mock the function you want to change the behaviour of.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜