Search code examples
eclipsejunitdependency-injectionrcpe4

How to use dependency injection in JUnit for Eclipse E4 plugin projects


When I set up a context in a JUnit test case to enable testing of a test object (E4 plugin project), which uses dependency injection for a service IMyServiceInterface, the result is always the same:

InjectionException: Unable to process "MyTestObject.myServiceInterface" no actual value was found for the argument IMyServiceInterface".

My idea is to set up a Eclipse context in a test case within JUnit and inject the test object together with its stubbed dependencies (i.e. not mocked).

The test object is a class used in a E4 plugin project and have a reference to an injected service interface.

I've tried several ways of setting up a context in a JUnit test case (with both ContextInjectionFactory.make(...) and InjectorFactory.getDefault().make(...)) to enable testing of the test object.

Here is a simplification of my test object (E4 plugin project) with its two dependencies; IMyServiceInterface and IMyPartInterface:

@Creatable
@Singleton
public class MyTestObject {

   @Inject IMyServiceInterface myServiceInterface;

   public void myMethod(IMyPartInterface myPartInterface) {
      this.myServiceInterface.update();
      myPartInterface.set();
   }

}

Here is a simplification of my test case (JUnit project):

class AllTests {

   @Test
   void myTestCase() {
        InjectorFactory.getDefault().make(MyPart_Stub.class, null);
        InjectorFactory.getDefault().make(MyService_Stub.class, null);
        MyTestObject myTestObject = InjectorFactory.getDefault().make(MyTestObject.class, null);
   }

}

Here are my stubbed dependencies (JUnit project):

public class MyService_Stub implements IMyServiceInterface {

   public void update() {
   }

}

public class MyPart_Stub implements IMyPartInterface {

   public void set() {
   }

}

When I run the test case I get: InjectionException: Unable to process "MyTestObject.myServiceInterface" no actual value was found for the argument IMyServiceInterface".


Solution

  • Finally I've understood whats wrong. I haven't been aware of the fact that ContextInjectionFactory.make(...) only creates an object (i.e. it doesn't inject it in the context as well). To inject the created object I also have to use the set method in the context. This is how I got my basic example to work:

    class AllTests {
    
       @Test
       void myTestCase() {
        IEclipseContext context = EclipseContextFactory.create();
        IMyPart myPart_Stub = ContextInjectionFactory.make(MyPart_Stub.class, context);
        context.set(IMyPart.class, myPart_Stub);
        IMyService myService_Stub = ContextInjectionFactory.make(MyService_Stub.class, context);
        context.set(IMyService.class, myService_Stub);
        MyTestObject myTestObject = ContextInjectionFactory.make(MyTestObject.class, context);
        context.set(MyTestObject.class, myTestObject);
       }
    
    }