I’m getting started with unit testing and trying to do some TDD. I’ve read a fair bit about the subject and written a few tests. I just want to know if the following is the right approach.
I want to add the usual “contact us” facility on my web site. You know the thing, the user fills out a form with their email address, enters a brief message and hits a button to post the form back.
The model binders do their stuff and my action method accepts the posted data as a model. The action method would then parse the model and use smtp to send an email to the web site administrator infoming him/her that somebody filled out the contact form on their site.
Now for the question …. In order to test this, would I be right in creating an interface IMessageService that has a method Send(emailAddress, message) to accept the email address and message body. Implement the inteface in a concrete class and let that class deal with smtp stuff and actually send the mail.
If I add the interface as a parameter to my controller constructor I can then use DI and IoC to inject the concrete class into the controller. But when unit testing I can create a fake or mock version of my IMessageService and do assertions on that.
The reason I ask is that I’ve seen other examples of people generating interfaces for SmtpClient and then mocking that. Is there really any need to go that far or am I not understanding this stuff?
You’d still need to test your class that invokes the mailer. I suggest that you might want to do a little of both. I typically create an IMailClient interface and a wrapper around SmtpClient that implements the interface. Use (and inject) the interface in a proxy class that knows how to construct the message and send it (it might have several factory-type methods that can construct multiple different types of messages). The shim around the SmtpClient really should be just that, thus there’s little need for unit testing it. You can mock your shim when testing the proxy class and mock your proxy class when testing your controllers.