1

I'm testing an (Eclipse 4) application (I'm not talking about unit test but more integration and system-test).

I've a recurrent problem I need to solve. I have to "inject" (@Inject) a context from the test into the class(es) under test. In other words I need the test does what the application usually do.

What I've done is creating a private method:

private IEclipseContext createApplicationContext() {
    IEclipseContext tempContext = E4Application.createDefaultContext();
    ContextInjectionFactory.make(CommandServiceAddon.class, tempContext);
    ContextInjectionFactory.make(ContextServiceAddon.class, tempContext);
    eventBroker = (IEventBroker) tempContext.get(IEventBroker.class.getName());
    tempContext.set(IEventBroker.class, eventBroker);
    return tempContext;
}

I expected (wrongly) that the context just created here would have been made available in one of the classes under test. E.g.:

class MyDBClassToTest {
   @Inject
   private IEclipseContext context;

   @Inject
   private IEventBroker broker;
   // ... etc
}

for sure there is something missing! I've created the activator too (below the implementation without comment for brevity) ... but didn't help:

import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

public class Activator extends AbstractUIPlugin {

    // The shared instance
    private static Activator plugin;

    // The plug-in ID
    public static final String PLUGIN_ID = "my.path....";

    public static Activator getDefault() {
        return plugin;
    }

    public Activator() {
    }

    @Override
    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;
    }

    @Override
    public void stop(BundleContext context) throws Excepti`enter code here`on {
        plugin = null;
        super.stop(context);
    }
}

any idea, hint or suggestion?

greg-449
  • 109,219
  • 232
  • 102
  • 145
Kasper
  • 685
  • 2
  • 11
  • 30

2 Answers2

1

You need to use ContextInjectionFactory.make with your context to create the class you want to test:

ContextInjectionFactory.make(MyDBClassToTest.class, tempContext);

or you can use ContextInjectionFactory.inject to inject in to a class that has already been constructed:

MyDbClassToTest myClass = new MyDbClassToTest();

ContextInjectionFactory.inject(myClass, tempContext);

only classes created using one of these methods are injected.

greg-449
  • 109,219
  • 232
  • 102
  • 145
  • Thanks :-) the problem is that MyDBClassToTest.execute call internally a method of an object that need itself the context injected ... and in general I'd like to "inject" or make available the context created in to the test to the whole application ..... is that possible? – Kasper May 24 '15 at 08:54
  • Sorry but I don't really understand your question - but as I said only classes created using one of these ContextInjectionFactory methods are injected. – greg-449 May 24 '15 at 09:23
0

You could just use any other lightweight injection framework that can inject into private fields.

For example using Mockito with @Spy (which allows real objects to be injected, not just mocks) and @InjectMocks. See this answer for an example.

Or write your own mini-injector. Here is an example (at the bottom of the post) for EJB, but you can adapt it to use the Eclipse annotations.

Community
  • 1
  • 1
jhyot
  • 3,733
  • 1
  • 27
  • 44