I think I've found a potential bug/ area for improvement.

We are setting up pure unit tests for a component, and in this test case, although the component declares several @SpringBean's, only 1 is used. Our tests all work fine when we run them against our "test" spring context, but I wanted to do something more isolated...

So, in our custom injector, we only inject the, let's call it, TemplatesDao object. The other 'dao's or whatever, remain un-attended to.

This runs fine, in one case, where we specify the names of the beans - i.e. @SpringBean(name="templateDao"), @SpringBean(name="peopleDao"), etc, where we ignore the peopleDao bean for example. The fields are all set to lazy proxy's, and the actual resolution of the bean only happens on first access - so, our peopleDao is never looked up (which wouldn't work, because it's not there), and our templateDao get's looked up successfully.

However, if we do not specify the name of the bean - i.e. with have another bean @SpringBean of type RoomsDao. When the wicket code goes to setup this field's lazy initialiser, it fails. It turns down the wrong road at:
SpringBeanLocator:
singletonCache = Boolean.valueOf(getSpringContext().isSingleton(getBeanName()));
which leads to the:
String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(ctx, clazz); This of course calls the getBeanName(). And because we didn't specify a name, the injector tries to ask Spring for it - which of course doesn't work, because no bean of that type actually exists in the conext.

IMO the treatment of named vs unnamed @SringBeans is thus sort of inconsistent, and would be useful for us to be able to not worry about unnamed bean types not existing. Is there a way to avoid this call into the Spring context?

One of the work arounds we can use for this, is to add a mock implementation of that class into the test application context, so spring is able to find a bean of that type. But I'd prefer not to have to :)

The other work around, is to not use the SpringComponentInjector, and instead setup our own ComponentInjector which only cares about the one panel we're testing:
    @Override
    public void onInstantiation(Component component) {
        if (component instanceof ProfileDetailPanel) {
            ProfileDetailPanel p = (ProfileDetailPanel) component;
            p.setProfileManager( mockProfileManager );
        }
    }


I wanted to get some thoughts, before I posted a Jira.

Regards,
Antony Stubbs,
NZ
http://friendfeed.com/astubbs

Reply via email to