Unit tests: should we avoid overspecification?

  • Say I have the following method that sends emails. I know I should have tests for the different status codes returned. I am also testing if the the methods CreateMail() and Send() are being called. I guess in the end what's important is if the success status is returned or not. Should I be testing if these methods are being called or not ? public void SendMail(Model model, out Status status) { if (!MyValidator.IsValidEmailAddress(model.EmailRecipient)) { status = Status.InvalidEmailAddress; return; } // code removed for clarity IEmailMessage email = _emailMessageBuilder.CreateMail(model); _mailerClient.Send(email); status = Status.Success; } [TestMethod] public void SendMail_CreateMailGetsCalledOnce() { ... } [TestMethod] public void SendMail_SendGetsCalledOnce() { ... }

  • You should avoid doing assertions on the method's innards as much as possible, to avoid coupling the unit tests to implementation specific details. In reality, of course, that's not always possible. In this case, you don't need to verify whether those methods were called. You're gonna have to provide a mock for _emailMessageBuilder, IEmailMessage and _mailerClient. If: the mailer client is setup to return a status code of 200 if it is asked to send the email created by the message builder, and if the message build is setup to return that email if it is asked to create an email for model, and if SendMail returns 200, then you can infer that the right methods were called. No need to explicitly verify this.

Log in to reply

Suggested Topics