Unit Tests and BlockingCondition [message #829338] |
Mon, 26 March 2012 06:53 |
Adrian Moser Messages: 67 Registered: March 2011 |
Member |
|
|
Is it possible to write Unit Tests when a Scout BlockingCondition is involved?
Since there is no user interaction, the BlockingCondition seems never to be resolved.
This happens especially when testing a menu which starts a form.
Any ideas?
|
|
|
|
|
|
|
|
|
Re: Unit Tests and BlockingCondition [message #832143 is a reply to message #829711] |
Thu, 29 March 2012 20:41 |
|
Hi Adrian
Possible deadlocks when running the tests is a known issue and very annoying. Unfortunately the scout testing framework does not provide a solution for this problem yet. Until there is one you can use the following helper functions resp. create similar ones for your specific case. Basically you need to register a ChangeListenerEx and release the waitFor by closing the form when it gets blocked.
Hope that helps.
Claudio
/**
* If clicking a button leads to a lock because execClickAction contains waitFor() no code can be executed until the
* lock is released.
* With this function it is possible to execute code just before the lock is installed.
* <p>
* The caller must ensure that the lock gets released (f.e. by canceling the form at the and of the runnable).
* </p>
*
* @param button
* @param runnableAfterButtonClick
* @throws ProcessingException
*/
public static void clickBlockingButton(IButton button, Runnable runnableAfterButtonClick) throws ProcessingException {
TestingExceptionHandlerService exceptionHandler = new TestingExceptionHandlerService();
List<ServiceRegistration> regs = TestingUtility.registerServices(Activator.getDefault().getBundle(), 1000, exceptionHandler);
WaitForListener waitForListener = new WaitForListener(runnableAfterButtonClick);
ClientJob currentJob = (ClientJob) ClientJob.getJobManager().currentJob();
currentJob.addJobChangeListenerEx(waitForListener);
try {
//click button which opens the form and blocks with waitFor()
button.doClick();
exceptionHandler.assertNoException();
exceptionHandler.clear();
}
finally {
currentJob.removeJobChangeListenerEx(waitForListener);
TestingUtility.unregisterServices(regs);
}
}
public static <T extends IForm> T findLastAddedForm(Class<T> formType) {
T[] forms = ClientSession.get().getDesktop().findForms(formType);
if (forms == null || forms.length == 0) {
return null;
}
return forms[forms.length - 1];
}
private static class WaitForListener extends JobChangeAdapterEx {
private Runnable runnable;
public WaitForListener(Runnable runnable) {
this.runnable = runnable;
}
@Override
public void blockingConditionStart(IJobChangeEvent event) {
try {
runnable.run();
}
catch (Throwable t) {
//Exception would be catched by the listener so it is necessary to use the exception service in order to make the test fail.
SERVICES.getService(TestingExceptionHandlerService.class).handleException(new ProcessingException("", t));
}
}
}
|
|
|
|
Re: Unit Tests and BlockingCondition [message #835127 is a reply to message #834997] |
Mon, 02 April 2012 20:48 |
|
Hi Adrian
There you go.
Claudio
/**
* Use this custom exception handler service to catch all exceptions (message boxes) and check for specific events
*/
public class TestingExceptionHandlerService extends AbstractService implements IExceptionHandlerService {
private ProcessingException m_lastException;
@Override
public void handleException(ProcessingException t) {
if (t != null) {
String message = t.getStatus().getMessage().replaceAll("\\s+", " ").trim();
System.out.println("consuming: " + message);
}
m_lastException = t;
}
public void assertNoException() {
if (m_lastException == null) {
return;
}
if (m_lastException.getCause() instanceof AssertionError) {
throw (AssertionError) m_lastException.getCause();
}
throw new RuntimeException(m_lastException);
}
/**
* similar means all whitespace is replaced by one space and all text is lower case for compare
*/
public void assertLastExceptionIsSimilarTo(Class<?> type, String message) {
Assert.assertNotNull(m_lastException);
Assert.assertEquals(type, m_lastException.getClass());
String expected = m_lastException.getStatus().getMessage().toLowerCase().replaceAll("\\s+", " ").trim();
String actual = message.toLowerCase().replaceAll("\\s+", " ").trim();
Assert.assertEquals(expected, actual);
}
public void clear() {
m_lastException = null;
}
}
|
|
|
Powered by
FUDForum. Page generated in 0.06835 seconds