怎样使MAILMESSAGE System.Net.Mail的样机? [英] How do I make a mockup of System.Net.Mail MailMessage?

查看:157
本文介绍了怎样使MAILMESSAGE System.Net.Mail的样机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我有些SMTP东西在我的code和我试图单元测试方法。

So I have some SMTP stuff in my code and I am trying to unit test that method.

所以,我一直在努力MAILMESSAGE样机,但它似乎永远不会工作。我想,没有一个方法是虚拟的或抽象的,所以我不能用MOQ嘲笑它:(

So I been trying to Mockup MailMessage but it never seems to work. I think none of the methods are virtual or abstract so I can't use moq to mock it up :(.

所以我想我必须做手工,这就是我在哪里卡住了。

So I guess I have to do it by hand and that's where I am stuck.

*用手我的意思是知晓的界面和包装,但让起订量仍样机的接口。

*by hand I mean witting the interface and the wrapper but letting moq still mockup the interface.

我不知道该怎么写我的接口与我的包装(当我真正的code运行时,它实际上是将实施将有MAILMESSAGE实际code所以接口的类做东西,它需要做)。

I don't know how to write my Interface and my Wrapper(a class that will implement the interface that will have the actual MailMessage code so when my real code runs it actually does the stuff it needs to do).

所以,首先我不知道如何设置我的连接。让我们来看看,我要对样机的领域之一。

So first I am not sure how to setup my Interface. Lets take a look at one of the fields that I have to mockup.

MailMessage mail = new MailMessage();

mail.To.Add("test@hotmail.com");

所以这是我有伪造的第一件事。

so this is the first thing that I have to fake.

这样看着它,我知道要是打了把它带我到这条线F12的属性:

so looking at it I know that "To" is a property by hitting F12 over "To" it takes me to this line:

public MailAddressCollection To { get; }

因此​​,它是MailAddressCollection属性。但是有些我怎么让我走得更远,做添加。

So it is MailAddressCollection Property. But some how I am allowed to go further and do "Add".

所以现在我的问题是在我的界面我该怎么做?

So now my question is in my interface what do I make?

让我的财产?应将此属性是MailAddressCollection?

do I make a property? Should this Property be MailAddressCollection?

或者我应该有这样的方法?

Or should I have a method like?

void MailAddressCollection To(string email);

or 

void string To.Add(string email);

那么如何将我的包装看?

Then how would my wrapper look?

因此​​,大家可以看到我很迷茫。既然有这么多他们。我猜我只是小样我现在用的人。

So as you can see I am very confused. Since there is so many of them. I am guessing I just mockup the ones I am using.

编辑code

我想在一个真正意义上的我将只需要测试更多的例外情况,但我想测试,以确保如果一切被发送那么它会得到响应=成功。

I guess in in a true sense I would only have to test more the exceptions but I want to test to make sure if everything gets sent then it will get to response = success.

string response = null;
            try
            {

                MembershipUser userName = Membership.GetUser(user);

                string newPassword = userName.ResetPassword(securityAnswer);

                MailMessage mail = new MailMessage();

                mail.To.Add(userName.Email);

                mail.From = new MailAddress(ConfigurationManager.AppSettings["FROMEMAIL"]);
                mail.Subject = "Password Reset";

                string body = userName + " Your Password has been reset. Your new temporary password is: " + newPassword;

                mail.Body = body;
                mail.IsBodyHtml = false;


                SmtpClient smtp = new SmtpClient();

                smtp.Host = ConfigurationManager.AppSettings["SMTP"];
                smtp.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["FROMEMAIL"], ConfigurationManager.AppSettings["FROMPWD"]);

                smtp.EnableSsl = true;

                smtp.Port = Convert.ToInt32(ConfigurationManager.AppSettings["FROMPORT"]);

                smtp.Send(mail);

                response = "Success";
            }
            catch (ArgumentNullException ex)
            {
                response = ex.Message;

            }
            catch (ArgumentException ex)
            {
                response = ex.Message;

            }
            catch (ConfigurationErrorsException ex)
            {
                response = ex.Message;
            }
            catch (ObjectDisposedException ex)
            {
                response = ex.Message;
            }
            catch (InvalidOperationException ex)
            {
                response = ex.Message;
            }
            catch (SmtpFailedRecipientException ex)
            {
                response = ex.Message;
            }
            catch (SmtpException ex)
            {
                response = ex.Message;
            }



            return response;

        }

感谢

推荐答案

为什么模拟MAILMESSAGE的?该SmtpClient接收MailMessages,发送出去;这是我想包用于测试目的的类。所以,如果你正在写一些类型的系统是放置订单,如果你想测试你的OrderService总是电子邮件时发出订单,你必须类似于以下的类:

Why mock the MailMessage? The SmtpClient receives MailMessages and sends them out; that's the class I'd want to wrap for testing purposes. So, if you're writing some type of system that places Orders, if you're trying to test that your OrderService always emails when an order is placed, you'd have a class similar to the following:

class OrderService : IOrderSerivce 
{
    private IEmailService _mailer;
    public OrderService(IEmailService mailSvc) 
    {
        this. _mailer = mailSvc;
    }

    public void SubmitOrder(Order order) 
    {
        // other order-related code here

        System.Net.Mail.MailMessage confirmationEmail = ... // create the confirmation email
        _mailer.SendEmail(confirmationEmail);
    } 

}

使用IEmailService包装SmtpClient的默认实现:

With the default implementation of IEmailService wrapping SmtpClient:

这样,当你去写你的单元测试,您测试使用SmtpClient / EmailMessage班,SmtpClient / EmailMessage类不行为的code的行为本身:

This way, when you go to write your unit test, you test the behavior of the code that uses the SmtpClient / EmailMessage classes, not the behavior of the SmtpClient / EmailMessage classes themselves:

public Class When_an_order_is_placed
{
    [Setup]
    public void TestSetup() {
        Order o = CreateTestOrder();
        mockedEmailService = CreateTestEmailService(); // this is what you want to mock
        IOrderService orderService = CreateTestOrderService(mockedEmailService);
        orderService.SubmitOrder(o);
    } 

    [Test]
    public void A_confirmation_email_should_be_sent() {
        Assert.IsTrue(mockedEmailService.SentMailMessage != null);
    }


    [Test]
    public void The_email_should_go_to_the_customer() {
        Assert.IsTrue(mockedEmailService.SentMailMessage.To.Contains("test@hotmail.com"));
    }

}

编辑:应对以下您的意见是,你要EmailService两个独立的实现 - 只有一个会使用SmtpClient,其中你会在你的应用code使用:

to address your comments below, you'd want two separate implementations of EmailService -- only one would use SmtpClient, which you'd use in your application code:

class EmailService : IEmailService {
    private SmtpClient client;

    public EmailService() {
        client = new SmtpClient();
        object settings = ConfigurationManager.AppSettings["SMTP"];
        // assign settings to SmtpClient, and set any other behavior you 
        // from SmtpClient in your application, such as ssl, host, credentials, 
        // delivery method, etc
    }

    public void SendEmail(MailMessage message) {
        client.Send(message);
    }

}

您嘲笑/伪造的电子邮件服务(你不需要为这个嘲弄的框架,但它可以帮助)不会碰SmtpClient或SmtpSettings;它会只记录的,在某些时候,电子邮件是通过SendEmail传递给它的事实。然后,您可以使用此测试SendEmail是否被调用,并与参数:

Your mocked / faked email service (you don't need a mocking framework for this, but it helps) wouldn't touch SmtpClient or SmtpSettings; it'd only record the fact that, at some point, an email was passed to it via SendEmail. You can then use this to test whether or not SendEmail was called, and with which parameters:

class MockEmailService : IEmailService {
    private EmailMessage sentMessage;;

    public SentMailMessage { get { return sentMessage; } }

    public void SendEmail(MailMessage message) {
        sentMessage = message;
    }

}

电子邮件与否的实际测试被送到了SMTP服务器和交付应属于你的单元测试的范围之外。你需要知道这是否工作正常,你可以设置第二组测试来专门测试这个(通常称为集成测试),但这些是不同的测试从​​code,测试您的应用程序的核心行为分开。

The actual testing of whether or not the email was sent to the SMTP Server and delivered should fall outside the bounds of your unit testing. You need to know whether this works, and you can set up a second set of tests to specifically test this (typically called Integration Tests), but these are distinct tests separate from the code that tests the core behavior of your application.

这篇关于怎样使MAILMESSAGE System.Net.Mail的样机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆