Home » Eclipse Projects » Riena » Unit testing "ordinary" IController implementations(What's the best way to unit test controller classes that don't extend SubModuleController?)
Unit testing "ordinary" IController implementations [message #543850] |
Wed, 30 June 2010 19:00 |
Christian Kesselheim Messages: 59 Registered: June 2010 |
Member |
|
|
Hi again,
just wanted to ask what's currently being considered the best way to unit test controller classes not extending SubModuleController. For example, how do I test AbstractWindowController implementations?
Using AbstractSubModuleControllerTest does clearly not qualify there, since the testing infrastructure relies on NavigationNodeController.getRidget(Class<R>, String) to create the dummy ridgets during our test.
Thanks in advance,
Chris
[Updated on: Wed, 30 June 2010 19:06] Report message to a moderator
|
|
|
Re: Unit testing "ordinary" IController implementations [message #543971 is a reply to message #543850] |
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 controllers 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 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 sub-classes.
* 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.AbstractWindowController;
@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.class, 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.SubModuleController;
import org.eclipse.riena.ui.ridgets.controller.IController;
import org.eclipse.riena.ui.ridgets.swt.uibinding.SwtControlRidgetMapper;
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_PROPERTY, "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_PROPERTY, "false"); //$NON-NLS-1$
super.tearDown();
}
protected C getController() {
return controller;
}
protected abstract C createController();
}
[Updated on: Thu, 01 July 2010 14:30] Report message to a moderator
|
|
|
Re: Unit testing "ordinary" IController implementations [message #544251 is a reply to message #543971] |
Fri, 02 July 2010 07:21 |
Christian Campo Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Hi Christian,
why dont you open a bug in Riena, create a patch for a general solution to test AbstractWindowControllers and attach
that patch to the bug......
Thats open source and you are right in the middle of it :-)
christian
Am 01.07.10 10:52, schrieb Christian Kesselheim:
> 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();
> }
>
>
>
|
|
|
Re: Unit testing "ordinary" IController implementations [message #586197 is a reply to message #543971] |
Fri, 02 July 2010 07:21 |
Christian Campo Messages: 597 Registered: July 2009 |
Senior Member |
|
|
Hi Christian,
why dont you open a bug in Riena, create a patch for a general solution to test AbstractWindowControllers and attach
that patch to the bug......
Thats open source and you are right in the middle of it :-)
christian
Am 01.07.10 10:52, schrieb Christian Kesselheim:
> 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();
> }
>
>
>
|
|
|
Goto Forum:
Current Time: Thu Apr 25 12:15:37 GMT 2024
Powered by FUDForum. Page generated in 0.75837 seconds
|