Search code examples
eclipseunit-testingmockingeclipse-rcpfixtures

How can I unit test Eclipse Command Handlers?


I have an Eclipse 3.x-based application which uses commands and handlers.

I'm in the process of upping the code coverage and want to test as much as I can. The simple cases (POJOs) I've learned how to test. However, there are cases where I can't find a good starting point, especially when creating a fixture.

For example: Eclipse Command Handlers. I have a handler class MyHandler extending org.eclipse.core.commands.AbstractHandler. It has a single method public Object execute(ExecutionEvent event) throws ExecutionException. Usually, event is passed in from a user action in the GUI, e.g., clicking a menu item.

How can I unit test this? Would I need to mock the ExecutionEvent with the help of a mocking framework?


Solution

  • Unless inevitable, I prefer to mock only types I do own. See here for a discussion of Should you only mock types you own?

    Since ExecutionEvents can be created without too much hassle I wouldn't mock them. The snippet below creates an event that you can pass to your handlers' execute method.

    IEvaluationContext context = new EvaluationContext( null, new Object() );
    Map<String, String> parameters = new HashMap<>();
    ExecutionEvent event = new ExecutionEvent( null, parameters, null, context );
    

    The first argument of the ExecutionEvent constructor references the command - I have never had any use for it. If your code requires an actual command, you can use the ICommandService to obtain a reference to your command:

    ICommandService commandService = ...
    Command command = commandService.getCommand( "id.of.my.command" );
    

    The second argument is a map of command parameters. The third argument is the trigger. If case of the Eclipse workbench this is the SWT Event if available. Leave it null if your production code does not evaluate it.

    Before calling execute, you would probably want to prepare the variables of the context:

    context.addVariable( ISources.ACTIVE_PART_NAME, myPart );
    context.addVariable( ISources.ACTIVE_CURRENT_SELECTION_NAME, new StructuredSelection() );
    

    Note that null is not allowed as a variable value. Either omit the call or - if already added, use removeVariable().

    If you don't need a command (see above) - and of course your production code doesn't require a workbench - you can even run the tests as plain JUnit tests (as opposed to PDE JUnit test).