|
Re: Unit testing "ordinary" IController implementations [message #586166 is a reply to message #586154] |
Thu, 01 July 2010 08:52 |
Christian Kesselheim Messages: 59 Registered: June 2010 |
Member |
|
|
For those who care: Here's the infrastructure code (read: hack) I use to test my AbstractWindowController.
All my window controller extend AbstractTestableWindowController, while all corresponding unit tests inherit from AbstractControllerTest.
Please note that this only a work-around for current shortcomings in Riena itself. Here's my wish-list to make this workaround unnecessary in the future:
* AbstractWindowController.getRidget(...) should behave similar to NavigationNodeController<ISubModuleNode>.getRidget(...) when invoked from within a unit test; that is: generate the (mock) ridgets automatically at the time they're first requested.
* There should be an equivalent to AbstractSubModuleControllerTest that people could use to unit test their AbstractWindowController.
* All relevant Riena classes should always check for null when calling getUIControl() on their ridgets (e.g. EmbeddedTitleBarRidget.dispose() or DefaultActionManager.activate() currently fail to do so).
package lu.kreios.mtg.client.controllers;
import java.lang.reflect.Modifier;
import org.eclipse.core.runtime.Assert;
import org.eclipse.riena.core.RienaStatus;
import org.eclipse.riena.internal.ui.ridgets.swt.ShellRidget;
import org.eclipse.riena.ui.ridgets.ClassRidgetMapper;
import org.eclipse.riena.ui.ridgets.IActionRidget;
import org.eclipse.riena.ui.ridgets.IRidget;
import org.eclipse.riena.ui.ridgets.IWindowRidget;
import org.eclipse.riena.ui.ridgets.controller.AbstractWindowContro ller;
@SuppressWarnings("restriction")
public class AbstractTestableWindowController extends AbstractWindowController {
public static final String WINDOW_RIDGET = "windowRidget"; //$NON-NLS-1$
public AbstractTestableWindowController() {
// This becomes necessary due to the fact the EmbeddedTitleBarRidget fails
// to check for getUIControl() returning null when called in the scope of
// its dispose() method.
ClassRidgetMapper.getInstance().addMapping(IWindowRidget.cla ss, ShellRidget.class);
}
@Override
public void addDefaultAction(IRidget focusRidget, IActionRidget action) {
// This becomes necessary due to the fact the DefaultActionManager fails
// to check for getUIControl() returning null when called in the scope of
// its activate() method. We'll ignore this for now, since there's no
// chance of any unit test hitting the ENTER key after all.
}
@SuppressWarnings("unchecked")
public <R extends IRidget> R getRidget(Class<R> ridgetClazz, String id) {
R ridget = (R) getRidget(id);
if (ridget != null) {
return ridget;
}
if (RienaStatus.isTest()) {
try {
if (ridgetClazz.isInterface()
|| Modifier.isAbstract(ridgetClazz.getModifiers())) {
Class<R> mappedRidgetClazz = (Class<R>) ClassRidgetMapper
.getInstance().getRidgetClass(ridgetClazz);
if (mappedRidgetClazz != null) {
ridget = mappedRidgetClazz.newInstance();
}
Assert.isNotNull(
ridget,
"Could not find a corresponding implementation for " + ridgetClazz.getName() + " in " + ClassRidgetMapper.class.getName()); //$NON-NLS-1$ //$NON-NLS-2$
} else {
ridget = ridgetClazz.newInstance();
}
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
addRidget(id, ridget);
}
return ridget;
}
@Override
public void setWindowRidget(IWindowRidget windowRidget) {
super.setWindowRidget(windowRidget);
}
@Override
public IWindowRidget getWindowRidget() {
return getRidget(IWindowRidget.class, WINDOW_RIDGET);
}
}
package lu.kreios.mtg.client.helpers;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.riena.core.RienaStatus;
import org.eclipse.riena.core.util.ReflectionUtils;
import org.eclipse.riena.internal.core.test.RienaTestCase;
import org.eclipse.riena.internal.core.test.collect.NonUITestCase;
import org.eclipse.riena.navigation.ui.controllers.SubModuleControl ler;
import org.eclipse.riena.ui.ridgets.controller.IController;
import org.eclipse.riena.ui.ridgets.swt.uibinding.SwtControlRidgetM apper;
import org.eclipse.swt.widgets.Display;
/**
* Abstract class for testing controllers that do NOT themselves extend {@link SubModuleController}.
* In any other case, please consider using the standard {@link AbstractControllerTest} class from
* Riena itself.
*/
@NonUITestCase
@SuppressWarnings("restriction")
public abstract class AbstractControllerTest<C extends IController> extends RienaTestCase {
private C controller;
@Override
protected void setUp() throws Exception {
super.setUp();
System.getProperties().put(RienaStatus.RIENA_TEST_SYSTEM_PRO PERTY, "true"); //$NON-NLS-1$
// only used to get the initial mappings
SwtControlRidgetMapper.getInstance();
Display display = Display.getDefault();
Realm realm = SWTObservables.getRealm(display);
assertNotNull(realm);
ReflectionUtils.invokeHidden(realm, "setDefault", realm); //$NON-NLS-1$
controller = createController();
controller.configureRidgets();
controller.afterBind();
}
@Override
protected void tearDown() throws Exception {
System.getProperties().put(RienaStatus.RIENA_TEST_SYSTEM_PRO PERTY, "false"); //$NON-NLS-1$
super.tearDown();
}
protected C getController() {
return controller;
}
protected abstract C createController();
}
|
|
|
Powered by
FUDForum. Page generated in 0.04325 seconds