0

An existing project that I work on, has a Spring bean that's created with Java:

@Configuration
public class BeansConfiguration
{
  @Autowired
  private Environment environment;

  @Bean(name = "edielbean")
  public EdielBean edielBean()
  {
    return new EdielBean();
  }
}

Now I want to access that bean from my unit test. My question is similar to How to access Spring context in jUnit tests annotated with @RunWith and @ContextConfiguration? except that my bean is not in XML but in Java.

I tried by adding this unit test (the camel parts can be ignored):

@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration(loader=AnnotationConfigContextLoader.class)
public class EdielBeanTest extends CamelTestSupport implements ApplicationContextAware {

private ApplicationContext context;

@Override
public String isMockEndpoints() {
  // camel
  return "*";
}

@Test
public void testSupplierSwitch() throws Exception
{
  getMockEndpoint("mock:market-out").expectedMessageCount(1); // camel
  System.out.println("beans: "+context.getBeanDefinitionCount());
  for (String name: context.getBeanDefinitionNames()) {
    System.out.println(name);
  }
  EdielBean edielBean = (EdielBean)context.getBean("edielbean");
  edielBean.startSupplierSwitch(createCustomer(), createOrder(), "54", "43");

  assertMockEndpointsSatisfied(); // camel
}

private Customer createCustomer()
{
  Customer customer = new Customer();
  // .... part omitted    
  return customer;
}

private Order createOrder() {
  Order order = new Order();
  // .... part omitted
  return order;
}

@Override
public void setApplicationContext(ApplicationContext context)
    throws BeansException {
  this.context = context;
}

}

The console output shows there are only trivial beans:

...
beans: 6
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessorSep 
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
...

test output:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'edielbean' is defined
    at
    ....
    at com.essent.belgium.ediel.services.EdielBeanTest.testSupplierSwitch(EdielBeanTest.java:42)
    at 
    ....
Community
  • 1
  • 1
Albert Hendriks
  • 1,644
  • 2
  • 20
  • 37

1 Answers1

1

I've never worked with Camel, so I'm not sure if this will work in your case, but this is how I would change your unit tests to work:

BeansConfiguration

@Configuration
public class BeansConfiguration
{
    @Autowired
    private Environment environment;

    @Bean(name = "edielbean")
    public EdielBean edielBean()
    {
        return new EdielBean();
    }
}

EdielBeanTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BeansConfiguration.class)
public class EdielBeanTest extends CamelTestSupport {

    @Autowired
    private ApplicationContext context;

    @Override
    public String isMockEndpoints() {
        // camel
        return "*";
    }

    @Test
    public void testSupplierSwitch() throws Exception
    {
        getMockEndpoint("mock:market-out").expectedMessageCount(1); // camel
        System.out.println("beans: " + context.getBeanDefinitionCount());
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }
        EdielBean edielBean = (EdielBean) context.getBean("edielbean");
        edielBean.startSupplierSwitch(createCustomer(), createOrder(), "54", "43");

        assertMockEndpointsSatisfied(); // camel
    }

    private Customer createCustomer()
    {
        Customer customer = new Customer();
        // .... part omitted
        return customer;
    }

    private Order createOrder() {
        Order order = new Order();
        // .... part omitted
        return order;
    }
}

I removed the implementation of ApplicationContextAware, Autowired the ApplicationContext, and changed @ContextConfiguration to point to your BeansConfiguration class. The last one may not be correct if the BeansConfiguration class is loaded by another JavaConfig class. In that case, you should point ContextConfiguration to the parent configuration.

LucasP
  • 1,425
  • 12
  • 22