Hi all,
Starting to get into MockBox and really liking it so far. We use it
standalone with mxUnit as our unit test framework. I will freely
admit that a) I am a relative newbie in this area and b) this question
is really more to do with mocking/unit testing in general vs any
mocking framework. But MockBox is what we are using so you guys get
to read my ramblings
My question is how to test the contract between a function and its
dependencies (be it internal or external) when you have mocked away
the dependency. I have created a rather contrived example below.
Say we have a component "a" that can take a string and either reverse
or not based on random chance. It relies on component "b" to take
care of the random chance part. It could like something like this.
component name="a" {
property any b;
//DI framework will handle this
public void function setB(any b){
variables.b = arguments.b;
}
public string function getRandomReverse(required string input){
if(variables.b.getRandomBool())
return reverse(arguments.input);
else
return arguments.input;
}
}
component name="b" {
public boolean function getRandomBool(){
return (rand() < .5);
}
}
So far so good. And now we want to unit test "a" and mock away the
dependency on "b"
component extends="mxunit.framework.TestCase"{
public void function testA(){
a= new a();
mockBox = new mockbox.system.testing.MockBox();
mockBox.prepareMock(a);
b = mockbox.createStub();
a.$property(propertyName="b",mock=b);
b.$("getRandomBool",false);
assertEquals(a.getRandomReverse("Lance"),"Lance");
b.$("getRandomBool",true);
assertEquals(a.getRandomReverse("Lance"),"ecnaL");
}
}
Still looks good. We are testing the functionality of
a.getRandomReverse in isolation and leaving something else to test
b.getRandomBool
But lets say down the road we modify b.getRandomBool to require a
weighting. So, for example, you pass it .75 it will return true 75%
of the time. component "b" now looks like this.
component name="b" {
public boolean function getRandomBool(required numeric weight){
return (rand() < arguments.weight);
}
}
If we fail to update the calling code in component "a" the function
getRandomReverse would be good and broken. But our unit test will
miss the breaking change because we have mocked away the dependency
and thus are never testing the contract.
So my question is...how do we handle this? How can I test the
software in isolation and still ensure our code is playing nicely with
it's dependencies? I feel like there is a whole other class of
testing that I am missing here.
Thanks in advance. And p.s. a link to a good web resource on this
scenario and a short note that says "read this and learn something" is
a perfectly acceptable answer
Lance