The problem occurs while doing TDD. After a couple of test pass, the return types of some class/module change. In a statically typed programming language, if a previous mocked object was used in the tests of some other class and was not modified to reflect the type change, then compilation errors will occur.
For dynamic languages however, the change in return types might not be detected and the tests of the other class will still pass. Sure there might be integration tests that should fail later on, but unit tests would erroneously pass. Is there any way how to avoid this?
Updating with a trivial sample (on some made up language)...
Version 1:
Calc = {
doMultiply(x, y) {return x * y}
}
//.... more code ....
// On some faraway remote code on a different file
Rect = {
computeArea(l, w) {return Calc.doMultipy(x*y)}
}
// test for Rect
testComputeArea() {
Calc = new Mock()
Calc.expect(doMultiply, 2, 30) // where 2 is the arity
assertEqual(30, computeArea)
}
Now, on version 2:
// I change the return types. I also update the tests for Calc
Calc = {
doMultiply(x, y) {return {result: (x * y), success:true}}
}
...Rect will then throw an exception on runtime, yet the test will still succeed.
class X
, but the tests ofclass Y
which depends onX
and thus gets tested against a different contract than what it runs against in production. – Bart van Ingen Schenau Jan 2 '13 at 17:11