Back in april last year we started looking into MDA and model transformations.
During a small research period we started using oAW as tool for this. Using oAW a
transformation is written for a large code generation framework.
With the introduction of oAW and modeling, new scripting languages are used to
transform the models into different artifacts (models and/or code).
The functional language of oAW is XTend. With XTend it is possible to write so
called extensions that can be used to query a model for information,
but also to create/change/update information with new/additional information.
Using a custom meta-model, or UML in combination with profiles, and a transformation,
it is possible to transform the model to any required artifact. OAW is used to
transform a UML model, marked with stereotypes, to XML. The XML is created using the XSD MetaModel support of oAW.
With the growing number of extensions, there was a need for a method to test these.
A logical solution is to create unit tests that can be used for regression testing.
This post describes a flexible way to write unit tests for extensions, including
mocking with EasyMock and Jmockit. Since this post is very technical, it is
assumed that the reader is familiar with oAW, UML and unit testing. More
information about oAW, EMF and Mocking can be found in the resources listed below the post.
Requirements
To be able to perform flexible and complete unit tests there are several requirements:
- Be able to call extensions from the unit test
- Be able to mock extensions
Extensions are written in XTend. To be able to unit test them, it must be possible
to call extensions from Java.
Extension heavily rely on other extension for querying or transforming.
With a unit test only the called extension must be tested. Each included extension
should have a test case of itself. So it must be possible to mock extensions and
be able to define the behavior inside the test case.
Approach
The following image shows an overview of the set up used to test extensions.

To realize this set up, the following approach is used:
- Call extensions from Java
- Mock extensions
- Advices
- XtendFacade
- Mocks
Extensions can be called from Java with a so called XtendFacade (link to oAW api).
This class will be used in the unit tests.
Mocking extensions involves some more work.
At first it must be possible to override the extensions that are called by the
extension to be tested. oAW includes AOP support, with which it is possible to
define advices that override extensions.
The facade that is part of oAW does not have support for advices. This
functionality must be added.
With advices and a custom facade it is possible to create stubs in which fixed
values can be specified. For functional testing it must be possible to mock
these stubs. To be able to do this JAVA extensions are used. From the advices a
java extension is called. The java method invoked by the extension can be mocked.
XtendFacade
An own implementation of the facade, with which it is possible to add advices is created. The advice argument must be a string pointing to the ext file with the advices.
The advices are registered to the context so that they are handled during the invocation of extensions.
public final void addAdvice(String advice) {
ctx.registerExtensionAdvices(advice.trim());
}
Advices
Now that it is possible to add advices to the Facade, it is possible to override extensions
MyXtendFacade f = createFacade("net::luminis::extensions::activator");
f.addAdvice("net::luminis::test::advices::createActivator");
Stubs
The overridden extensions can be used as stubs. Controlled responses can be declared, and helper extensions can be added to check/validate input.
around net::luminis::extensions::activator::createActivator(*): // test behavior
Mocks
Mocks are more flexible and give more/better validation options.
For an interesting read, see an article of Martin Fowler linked at the end of this post.
The original extension can’t be mocked, this is solved by using the overridden extensions.
Since there is no mocking library for XTend, the overridden functions must forward their invocation to a java method.
For each extension a java method is created. This method is called from the overridden extension.
Class test_createActivator():
JAVA net.luminis.test.helpers.Helper.test_createActivator();
around net::luminis::extensions::activator::createActivator(*):
test_createActivator();
EasyMock
Since the java method is static, and can’t easily be mocked, an extra interface is used.
The class containing the static methods has a public static field of the interface.
The interface declares a method for each static method. From the unit test this field
can be assigned during the setup phase. The interface method is called from the static method.
Now the interface can be used, in combination with eg EasyMock, to mock extensions.
To create the mock:
helperMock = createMock(HelperFactory.class); Helper.f = helperMock;
Use the mock:
// record the expected calls
expect(helperMock.test_createActivator()).andReturn(returnValue);
replay(helperMock);
// run tests
f.call("addActivator", parameter1, parameter2);
// assert results
assert...(...);
// verify the mock
verify(helperMock);
JMockit
As an alternative, another library can be used. While most mock libraries do not
support mocking static methods, this is possible with JMockit by instrumenting the
code (requires java 1.5 and up). An agent is added to the JVM that performs the instrumentation.
In the test case the static method can be mocked, and a controlled response can be given for each method.
Create the mock:
helperMock = createMock(HelperFactory.class); Helper.f = helperMock;
Use the mock:
// define the expected behavior
new Expectations(true) {
Helper mock;
{
mock.test_primitiveTypesModel();
returns(model);
mock.test_createPackageImport();
returns(packageImport);
mock.test_createActivator();
returns(activator);
}
};
// run tests
f.call("addActivator", parameter1, parameter2);
In the case of EasyMock some more work is needed to set up the java methods that are
called from the extensions. But the testing code is easier to create/update.
EasyMock also has more options with regards to behavioral checking. Furthermore,
EasyMock has a larger user base, so more people will likely be known with it
compared to JMockit.
Conclusion
Using the proposed method it is possible to write unit tests for oAW extensions.
These unit tests can be integrated in continuous build environments, so that it is
possible to have proper validation of a transformation.
This post does not handle the creation of test models (UML and/or XSD based),
but there are enough sources to find more information about the use of EMF
(which is used, by oAW, to load models) in general.
