May 292010
 

Finally, it’s done. I’ve released the first version of the ScalaEasyMock library (the naming is not very original, I have to admit).

ScalaEasyMock is a wrapper around the EasyMock library that focuses on mock controls and EasyMock Class Extension.

It provides a convenient, easy to use DSL for mock controls that makes heavy use of Scala manifests. Additionally, it contains helper classes that make it easy to create test objects with constructor arguments and partial mocks.

The library can be found on Google code, together with some documentation I’ve written:

Tutorial – scalaeasymock – Project Hosting on Google Code.

Happy mocking!

 Posted by at 14:48
May 132008
 

Are mock objects serializable? Sound’s like an idiot’s question, since no sane guy would ever consider serializing something that doesn’t really exist – that’s like trying to go to the basement of a movie mockup building.

However, as it often happens in a programmer’s life, sometimes you’re forced to behave weird. Especially with mock objects if you’re trying to feed them into a third-party library.

What I was doing is mocking parts of my application to do unit tests on a business process workflow written with Jboss’ jBPM. Specifically, I was testing a script embedded in the workflow’s XML (which prevents me from skipping the whole jBPM business and do straight tests on my Java classes).

The script calls an object that I have mocked, and I want to verify that the result gets written to the workflow’s execution context (that’s the data storage underlying it, basically a String->Object map):

There’s one big problem: jBPM is a framework with intrinsic persistence (using Hibernate) and any object written to a workflow’s execution context must be serializable (!). As I found out (the hard way, as it is often with these things): mock objects created using EasyMock (specifically, EasyMock Class Extensions) are *not* serializable, even if the class they pose as is…

When I ran straight into NotSerializableException, I tried to find ways around it. A possible tsrategy would be to add a special type converter to jBPM that allows mocks – but changing the code to be tested for testing is bad.

I thought of a lot bad solutions, I have to admit. However, the one I finally came up with is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MySerializableTest {
 
	/**
	 * The serializable class to mock.
	 */
	public static class MySerializable implements Serializable {
		private static final long serialVersionUID = -242728243854443748L;
	}
 
	/**
	 * The class that will be actually mocked. Neither the
	 * {@link MockedMySerializable#readExternal(ObjectInput)} nor
	 * {@link MockedMySerializable#writeExternal(ObjectOutput)} method will do
	 * anything - they are just there to be mocked.
	 */
	public static class MockedMySerializable extends MySerializable implements Externalizable {
 
		@Override
		public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 
                {
			/* do nothing */
		}
 
		@Override
		public void writeExternal(ObjectOutput out) throws IOException {
			/* do nothing */
		}
	}
}

This does the trick: instead of mocking the class that implements java.io.Serializable, I create a subclass of it that implements java.io.Externalizable (for those who don’t know: that’s kind of the ‘big brother’ of Serializable which lets the user implement the actual serialization himself. Of course, I provide only a dummy implementation. Nothing will be serialized for real here, it’s just to keep the code that invokes serialization from crying.

Of course, the mock created must either be a nice mock or actually expect the writeExternal(..) method to be called. But that’s just a routine task…

May 172006
 
Author: Tom Murphy VII - licensed under cc-by-sa Tom Murphy VII CC BY-SA

Sorry, this entry is only available in Deutsch.