Following my previous post I discovered a very helpful email in my inbox from Johannes Link, the author of MockMe, who provided an example of using MockMe to unit test my PrototypeJS classes.
One of the benefits of MockMe, vs JSMock or Jack, is it’s observance of the 3-A’s pattern (Arrange Act Assert), I quote:
- Arrange is variable declaration and initialization.
- Act is invoking the code under test.
- Assert/verify that expectations were met.
Both Jack and JSMock require expectations to be declared ahead of the ‘Act’, breaking the above pattern. This isn’t a ‘bad thing’, but reflecting on my long experience with EasyMock, it can lead to clutter in tests, reduce re-usability somewhat and can make tests more brittle and require more effort during refactorings.
I have copied the same Prototype class code as for the previous example; once again we obviously need to include the mockMe.js file in our script declarations:
<script type="text/javascript" src="your-path-to/mockMe-version.js"></script>
Objects defined using Class.create:
var ContainedObject = Class.create({
calcMaxMethodName: function() {
return -1;
},
calcMinMethodName: function() {
return -1;
},
getChildren: function() {
return [];
}
});
var ContainerObjectIMade = Class.create({
initialize: function(containedObject) {
this.delegate = containedObject;
},
doSomething: function() {
return {
"min": this.delegate.calcMinMethodName(),
"max": this.delegate.calcMaxMethodName(),
"children": this.delegate.getChildren()
};
}
});
Now for the test:
function testExample() {
var mocker = new Mocker();
mocker.mockClass(ContainedObject);
when(ContainedObject.prototype.calcMaxMethodName)().thenReturn(100);
when(ContainedObject.prototype.calcMinMethodName)().thenReturn(7);
when(ContainedObject.prototype.getChildren)().thenReturn(2);
var containerInstance = new ContainerObjectIMade(new ContainedObject());
var json = containerInstance.doSomething();
verify(once(), ContainedObject.prototype.calcMaxMethodName)();
verify(once(), ContainedObject.prototype.calcMinMethodName)();
verify(once(), ContainedObject.prototype.getChildren)();
assertEquals(77, json.min);
assertEquals(101, json.max);
assertEquals(expectedArray, json.children);
}
As you can see, this approach is very concise indeed, thanks Johannes!

