代码之家  ›  专栏  ›  技术社区  ›  Miyagi Coder

我的单元测试是否足够?

  •  1
  • Miyagi Coder  · 技术社区  · 15 年前

    我正在查看我为电子邮件服务编写的单元测试(使用SMTP),我想知道一个测试是否足够。以下是我的电子邮件服务的一个片段:

    [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
         }
    }
    

        [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();
    
        }
    

    这对于单元测试来说足够了吗?我能做些什么来改进它?

    我担心仅仅检查我的方法是否返回true并不是一个充分的单元测试。

    4 回复  |  直到 13 年前
        1
  •  2
  •   Allen Rice 0x6A75616E    15 年前

    提高你的 code coverage (所有类型)

        2
  •  2
  •   Paul Kuykendall    15 年前

    我建议您也包括在满足各种可能的错误条件时“成功”的否定测试。例如,传入无效的电子邮件地址,并验证是否返回了正确的错误代码和/或异常。

    this SMTP server mock site . 我在Java项目的电子邮件插件测试中使用了类似的方法。这样,您就不必关心它是否处于“测试模式”或生产模式。唯一的区别是配置中的服务器/端口组合。这样做的另一个好处是确保您不仅仅是在测试“测试代码”。

        3
  •  2
  •   ijw    15 年前

    发送电子邮件会失败吗?如果可以,您至少有两个案例需要测试,而您的单个测试是不够的。

    由于您有一个布尔返回值,这就向我表明您期望的是两个返回码中的一个,所以您也没有测试所有的可能性。

    更不用说,在发送电子邮件时,返回值是函数结果中最不重要的:电子邮件是否已发送?

        4
  •  1
  •   Yishai    15 年前

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

    这是一种代码气味。您应该传入电子邮件地址,并确保使用作为方法参数传入的内容调用服务,并使用mock确保正确地将其发送到电子邮件api。换句话说,模拟电子邮件api,不要将模拟本身用作测试主题。