Is my Unit Test sufficient?

I am looking at Unit tests I wrote for an email service (using SMTP) and I am wondering if one test is enough. Here is a snippet of my post service:

[PluginFamily("EmailService")]
public interface IEmailService
{
    Boolean SendEmail( string toAddress, string fromAddress, string bccAddress,  string ccAddress, string subject,
                       string body, bool html );
}
[Pluggable("EmailService")]
public class EmailService : IEmailService
{
    private IConfigurationReader _configReader;
    public EmailService(IConfigurationReader configurationReader)
    {
        _configReader = configurationReader;
    }
    public bool SendEmail( string toAddress, string fromAddress, string bccAddress, string ccAddress, string subject, string body, bool isHtml )
    {
        MailMessage email = new MailMessage();

        try
        {
            if (_configReader.TestMode)
            {
                toAddress = _configReader.TestEmailAddress;
            }
        }

        //send email here
     }
}

      

I poke fun at the IConfigurationReader (basically a wrapper for the ConfigurationManager) and set test mode to true to test if I can send an email in my "test mode". So my unit test looks something like this (this is one of my unit tests in a method. I have 100% code coverage):

    [Test]
    public void Validate_Send_Email_In_Test_Mode()
    {
        bool result;
        MockRepository mockRepository = new MockRepository();
        var mockConfigReader = mockRepository.StrictMock<IConfigurationReader>();


        using (mockRepository.Record())
        {

            SetupResult.For(mockConfigReader.TestMode).Return(true);
            SetupResult.For(mockConfigReader.TestEmailAddress).Return("test@test.com");
            SetupResult.For(mockConfigReader.EmailContentLocation).Return("test");
            SetupResult.For( mockConfigReader.SmtpHost ).Return( "test.mail.com" );
        }

        ObjectFactory.InjectStub(typeof(IConfigurationReader), mockConfigReader);
        emailService = ObjectFactory.GetInstance<IEmailService>();

        using (mockRepository.Playback())
        {
            result = emailService.SendEmail( "testemail@test.com",
                                                  "test@test.com", "", "",
                                                  "this is a unit test - config in test mode", "body of unit test", true );

        }

        Assert.That( result, Is.True );
        ObjectFactory.ResetDefaults();

    }

      

Is this enough for a unit test? What can I do to improve it?

I'm concerned that just checking that my method returns true isn't a sufficient unit test.

+1


a source to share


4 answers


Improve your code coverage (all types)



+2


a source


I would recommend that you also include negative tests that are "successful" when various possible error conditions are met. For example, enter an invalid email address and verify that the correct error code and / or exception is returned.



You may also want to create your own SMTP server. Although I didn't search much, I found this SMTP server layout site . I used a method similar to this for my testing of the Java project email plugin. So you don't care if it's in "test mode" or production. The only difference is the server / port combination in your configuration. This has the added benefit of ensuring that you are not just testing "test code".

+2


a source


Could email sending crash? If possible, you have at least two cases to test and your only test is insufficient.

Since you have a boolean return value, this tells me that you are expecting one of the two return codes, so again you are not checking all possibilities.

Not to mention, when sending an email, the return value is the least important of the function's results: Has the email been sent?

+2


a source


I would say this part:

    {
        if (_configReader.TestMode)
        {
            toAddress = _configReader.TestEmailAddress;
        }
    }

      

Is the code smell. You have to go in the mailing address and make sure the service is called with what you passed as a parameter to the method and use mock to make sure it was sent to the email api correctly. In other words, to poke fun at the e-mail api, don't use Mock as a test object by itself.

It might help you experiment with writing this differently, check first where production code is being written only if you can do a test that justifies writing it.

+1


a source







All Articles