Stubbing and Mocking
What can we make it do?
Once you have prepared some Mockolate, you probably want it to do something instead of just being given something false-y all the time.
Both nice and strict Mockolates can be setup to do one or more of:
- return a value, or sequence of values
- dispatch an event
- call another function
- throw an Error
Stubbing and mocking
Mockolate supports adding required behaviour using mock(instance)
and optional behaviour using stub(instance)
. These required and optional behaviours are called Expectation
s in Mockolate.
Any methods or properties with expectations added using mock(instance)
MUST be used in the test before the Mockolate is verified, otherwise Mockolate will throw an ExpectationError
telling you which expectations were not used.
var flavour:Flavour = nice(Flavour);
var yucky:Flavour = nice(Flavour);
var yummy:Flavour = nice(Flavour);
mock(flavour).method("combine").args(yummy);
flavour.combine(yucky);
verify(flavour);
Oh no, in the above example an ExpectionError
is thrown because we called flavour.combine()
with the wrong arguments. If we try that again with the correct arguments then our Mockolate will verify successfully.
var flavour:Flavour = nice(Flavour);
var yucky:Flavour = nice(Flavour);
var yummy:Flavour = nice(Flavour);
mock(flavour).method("combine").args(yummy);
flavour.combine(yummy);
verify(flavour);
Methods or properties with behaviour added using stub(instance)
are much nicer, and allow you add behaviour that might be used.
How to make Mockolates do something
In these examples we’re going to skip the [Test]
block and focus just on stubbing. All the usages of stub(flavour)
in these examples could be replaced with mock(flavour)
if we want to require that behaviour to be used.
Using a nice Flavour,
var flavour:Flavour = nice(Flavour);
we can stub a getter,
stub(flavour).getter("name").returns("Butterscotch");
or a setter,
stub(flavour).setter("name").arg(true);
or a method with no arguments, and return a value,
stub(flavour).method("toString").returns("Butterscotch");
stub a method with arguments, and return a reference,
var otherFlavour:Flavour = nice(Flavour);
var combinedFlavour:Flavour = nice(Flavour);
stub(flavour).method("combine").args(otherFlavour).returns(combinedFlavour);
stub a method with arguments using Matchers from hamcrest-as3
stub(flavour).method("combine").args(instanceOf(Flavour))
.returns(combinedFlavour);
stub a setter with arguments using Matchers,
stub(flavour).setter("ingredients").arg(array("cookies", "cream"));
stub a method to dispatch an Event,
stub(flavour).method("combine").args(anything())
.returns(combinedFlavour)
.dispatches(new FlavourEvent(FlavourEvent.TASTE_EXPLOSION));
stub a method to call a Function,
stub(flavour).method("combine").args(anything())
.returns(combinedFlavour)
.calls(function():void {
trace("its a mystery flavour");
});
stub a method to throw an Error,
stub(flavour).method("combine").args(nullValue())
.throws(new ArgumentError("Really, combine this flavour with <null>?"));
Customising behaviour
Additional behaviour not included in Mockolate can be added by implementing mockolate.ingredients.answers.Answer
. Examples of custom Answer
s are provided for handing HTTPService
result and fault calls. Decorating Mocolates has more details.