Daniel Cazzulino, author of Moq posted a good comment on my last post where I suggested looking into a Mockito like syntax for .NET Mock Frameworks.
On the surface, Mockito's approach seems good. But if you do the "true" comparison, you'll see that stub(...) is exactly the same as mock.Expect(...) in Moq.
Then, when you do verify(...), you have to basically repeat the exact same expression you put in stub(...). This might work if you only have a couple calls to verify, but for anything else, it will be a lot of repeated code, I'm afraid.
I thought this too. See my comment here from a month ago. Szczepan made a good point and I've thought about it more since then.
When combined with my position on loose vs strict mocks (almost always use loose), I'd say that *most* of the time you are either stubbing or verifying. Meaning, if you're verifying you don't need to stub unless of course that method returns something that is critical to the flow of your test, in which case you don't really need to verify, because the flow would have verified. That's a mouthful, but does that make sense?
I haven't used mockito, and I know there are times I use Expect.Call with return values that matter (which would essentially require you to duplicate stub & verify), but maybe that's a smell? Maybe if you think you need that you can do state based testing or change your API?
Here's an example Test using Rhino.Mocks:
[Test]
public void SomeMethod_Always_CallsSendMail()
{
IMailSender sender = mocks.DynamicMock();
UnderTest underTest = new UnderTest(sender);
using (mocks.Record())
{
Expect.Call(sender.SendMail()).Returns(true);
}
underTest.SomeMethod();
mocks.Verify(sender);
}
And some code this is testing (obviously not test driven, but you get the idea):
public void SomeMethod()
{
if (!_sender.SendMail())
{
throw new Exception("OH NOS");
}
}
Notice that here we would need to stub and verify separately with Mockito like syntax. This would look something like this:
[Test]
public void SomeMethod_Always_CallsSendMail()
{
IMailSender sender = mocks.DynamicMock();
UnderTest underTest = new UnderTest(sender);
Stub.That(() => sender.SendMail()).Returns(true);
underTest.SomeMethod();
Verify.That(() => sender.SendMail()).WasCalled();
}
This may violate DRY, but what if you designed your API differently? Maybe SendMail should throw an exception on failure instead of returning a boolean? This would make the return value unnecessary and remove the need for the Stub call. Clearly you can't always do this, especially with unwrapped legacy or API code, but it's something to think about.
Also, I think you shouldn't be verifying more than one method generally to go along with the one assert/test rule, so a single repeat would not be that horrendous. Heck, you could even do:
[Test]
public void SomeMethod_Always_CallsSendMail()
{
IMailSender sender = mocks.DynamicMock();
UnderTest underTest = new UnderTest(sender);
Stub.That(var sendMail = () => sender.SendMail()).Returns(true);
underTest.SomeMethod();
Verify.That(sendMail).WasCalled();
}
I think the syntax would lead to better, more concise tests. But maybe it would just be too annoying? I wouldn't know until I tried it for a while I guess.