0

I have a @SessionScoped bean that does some initialization at construction by calling various services (accessed via a service-locator). I would like to test if the initialized state of the bean is correct after its creation.

The bean looks something like this:

@ManagedBean
@SessionScoped
public class MyBean extends MyBeanBase {

    public MyBean(){
        init();
    }

    private void init(){
        //call service-methods to initialize some fields of the bean
    }

    ...
}

The class MyBeanBase contains a singleton-instance of a MyServiceLocator that exposes some services:

@ManagedBean(name="...")
@ApplicationScoped
public class MyServiceLocator{
    @EJB
    private Service1 service1;

    @EJB
    private Service2 service2;

    ...

    // getters for services
}

I use the Mockito mocking framework for my unit-tests. My initial idea was to mock the services that get called in the constructor and inject these mocks into the bean instance, but this does not work, because Mockito needs an instance of the class to be able to start mocking, but the service methods get called in the constructor itself.

My second idea was to move the bean-initialization into a @PostConstruct method like this:

@ManagedBean
@SessionScoped
public class MyBean extends MyBeanBase {
    private MyType field1;
    ...

    @PostConstruct
    private void init(){
        //call service-methods to initialize some fields of the bean
        field1 = getService1().getValue();
        ...
    }

    ...
}

I read some other threads discussing this case and suggesting the use of SpringJUnit4ClassRunner and @Autowired, but I'm not 100% sure if this is the correct approach in this case.

So basically what I would like to do is use mocked services to test if the bean gets initialized correctly using those services. My questions are:

  • What is the best approach for this problem?
  • Is there a better way to design the bean so that its initialized state can be tested easily?
  • Does testing the state of the bean even make sense in a unit-test?
  • Show us the code. Where do the service come from? Why do you use CDI, which is a dependency injection framework, whose point is to make your code easily testable by injecting collaborators, and still use a service locator, that makes your code untestable? – JB Nizet Jun 09 '15 at 09:36
  • I updated the code. The base-class of the bean contains an instance of the servce-locator. I'm not quite sure about the design principals used here, because this is legacy code, so this is what I have to work with at the moment. If it's possible, I wouldn't make bigger design-changes on the existing codebase. – József Legoza Jun 09 '15 at 09:48
  • inject a mock locator in MyBean, configure this mock locator to return mock services, and then call the init() method and test it does what it should. – JB Nizet Jun 09 '15 at 10:19
  • Thank you, this approach seems to be working fine. I thought about this earlier but I wanted to keep the method for initialization private. I guess it's ok to have a public `@PostConstruct` method in the bean. – József Legoza Jun 09 '15 at 10:38
  • You can make it package private or protected if you prefer. – JB Nizet Jun 09 '15 at 10:43

0 Answers0