This just came up in my study of TDD over Objective C. When using a mock rember that they fail-fast on unexppected invocations but ignore expectations that didn’t occur. In other words, if you set an expectation and your code does NOT meet the expectation then you will not get a failing test. Instead, you must manually call verify on the mock to get failures on unmet expectations. Consider the following mock:
//I like to interpolate comments when I use JMock. //Read these samples out loud if ya' feelin' me... completedTaskRecordMock.expects().once() /* a call to a */.method( /* named */ "cleanedTheBathroom"); myTerribleSpouse.doHouseWork((CompletedTaskRecord)myTerribleSpouseMock.proxy());
It will pass no matter how long myTerribleSpouse farts around on YouTube and LimeWire. In fact, myTerribleSpouse never once has to lift the bottle of Lysol to get a greenbar! However, if myTerribleSpouse calls orderPizza() on our mock then myTerribleSpouse is in for a failing test! What you need is to verify myTerribleSpouse meets your expectations. Check this out:
completedTaskRecordMock.expects().once() /* a call to a */.method( /* named */ "cleanedTheBathroom"); myTerribleSpouse.doHouseWork((CompletedTaskRecord)myTerribleSpouseMock.proxy()); /*using our */ completedTaskRecordMock /*we need to*/ .verify();
Best practice suggests we call verify in our tearDown method. Let me warn you, if you’re doing true TDD then you’ll hit a bump when you realize that assertionErrors raised in tearDown hide assertionErrors in the test. For that reason I suggest keeping calls to verify in the actual test methods as painfull as it is. I’m sending this out because it appears OCMock works similar to JMock 1.x in that mocks must be verified. I haven’t done much with JMock 2 or other mocking frameworks so I can’t speak on it. Still, it’s a heads up for those of you expecting red but seeing green. If ya’ true to the art of TDD then y’all know what I’m sayin’, right?