Thursday, September 14, 2006

Java mocking without injection, same line count as Mocha

The Ruby Mocha/Stubba mocking framework written by James Mead allows one to code collaboration expectations very clearly in very few lines.

Stephen Chu has expressed some disbelief that the same would be as readable in Java. However I've found that I can mock in Java with comparable clarity in the same number of lines as Ruby.


public class LaptopTest extends picounit.TestCase
public void powerOnFailsWhenBatteryTooLow(Battery anyBatteryInstance) {
should.call(anyBatteryInstance.meter()).andReturn(9);

Laptop laptop = new Laptop();
laptop.powerOn();

verify.that(laptop.powerStatus()).isEqualTo(Power.Off);
}
}



I've implemented many different ways of mocking in PicoUnit, all of them using some flavour of dependancy injection.

I haven't actually implemented the above one which requires much more infrastructure, it requires that PicoUnit modify every single class under test, specifically it requires all methods of all classes to have a pre-check injected into it (by altering the bytecode during class loading) for whether the method in question is being mocked and a subsequent redirect into PicoUnit if it is or a fall-through into the ordinary code if it isn't.

I've already done plenty of class bytecode manipulation / observation for PicoUnit, many of the features of PicoUnit would be impossible without this, there's so much bytecode stuff going on that PicoUnit has its own mini-framework for just this purpose, so I should be able to implement injectless mocking easily enough.