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".
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);
}
}