2016-10-31 10 views
1

System.ArgumentNullException сбрасывается с System.Web.HttpBrowserCapabilities конструктор, когда mail.Send() из теста называется. Он требует параметра httpBrowserCapabilities.Единичная проверка отправки почты почтой и moq

Код я использовал:

EmailModel:

public class EmailModel :Email 
{ 
    public EmailModel() :base("EmailModel") 
    { 

    } 
    public string To = "**********@gmail.com"; 

    [Display(ResourceType = typeof(Resource), Name = "Name")] 
    [Required(ErrorMessageResourceName = "Error_NameRequired", ErrorMessageResourceType = typeof(Resource))] 
    public string Name { get; set; } 

    [DataType(DataType.EmailAddress)] 
    [Display(ResourceType = typeof (Resource), Name = "Email")] 
    [Required(ErrorMessageResourceName = "Error_EmailRequired", ErrorMessageResourceType = typeof(Resource))] 
    [RegularExpression("[email protected]+", ErrorMessageResourceName = "Error_EmailWrong", ErrorMessageResourceType = typeof(Resource))] 
    public string Email { get; set; } 

    [Display(ResourceType = typeof(Resource), Name = "Topic")] 
    [Required(ErrorMessageResourceName = "Error_TopicRequired", ErrorMessageResourceType = typeof(Resource))] 
    public string Topic { get; set; } 

    [Display(ResourceType = typeof(Resource), Name = "Massage")] 
    [DataType(DataType.MultilineText)] 
    [Required(ErrorMessageResourceName = "Error_MassageRequired", ErrorMessageResourceType = typeof(Resource))] 
    public string Massage { get; set; } 
} 

Вид сообщения:

@model *******.Models.EmailModel 
@{ 
    Layout = null; 
} 
To: @Model.To 
Subject: @Model.Topic 

The massage from @Model.Name @Model.Email 
Massage text: 
@Model.Massage 

UnitTest:

public class EmailSetter 
{ 
    public const string DefaultName = "NameTest"; 
    public const string DefaultEmail = "[email protected]"; 
    public const string DefaultTopic = "TopicTest"; 
    public const string DefaultMassage = "Massage test."; 
    public EmailModel GetEmail(string Name = DefaultName, string Topic = DefaultTopic, string Email = DefaultEmail, string Massage = DefaultMassage) 
    { 
     EmailModel email = new EmailModel(); 
     email.Name = Name; 
     email.Topic = Topic; 
     email.Email = Email; 
     email.Massage = Massage; 
     return email; 
    } 
} 
[TestClass] 
public class MailTests 
{ 
    [TestMethod] 
    public void MailSendWithRightModel() 
    { 
     //Arrange 
     HomeController controller = new HomeController(); 
     Mock<EmailModel> email = new Mock<EmailModel>(); 
     email.Object.Name = EmailSetter.DefaultName; 
     email.Object.Email = EmailSetter.DefaultName; 
     email.Object.Topic = EmailSetter.DefaultTopic; 
     email.Object.Massage = EmailSetter.DefaultMassage; 
     //Act 
     controller.Contact(email.Object); 
     //Assert 
     email.Verify(mail => mail.Send()); 
    } 
} 

контроллер из теста:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Contact(EmailModel emailModel) 
{ 
    if(ModelState.IsValid) 
    { 
     ViewBag.Send = true; 
     emailModel.Send(); 
     ModelState.Clear(); 
    } 
    return View(emailModel); 
} 

То, что я пытался (в методе модульного тестирования):

  1. создания new HttpBrowserCapabilities через new BrowserCapabilitiesFactory

  2. создание new HttpBrowserCapabilitiesWrapper с HttpBrowserCapabilities объекта

Любые идеи, как сделать код не t o исключить исключение? (Т.е. сделать текущий HttpBrowserCapabilitiesWrapper прибудет существующие HttpBrowserCapabilities) :)

+2

Вы сделали несколько заявлений. Но каков ваш вопрос? – Jasen

+1

Вы пытаетесь отправить фактический адрес электронной почты (интеграционный тест) или намерены высмеять отправку электронной почты? Скорее всего, электронная почта пытается отправить электронное письмо, но правильные зависимости не были настроены для теста. – Nkosi

+0

Я пытаюсь проверить, будет ли вызываться метод Send, если правильная модель передается контроллеру. Я тоже думаю, что проблема связана с зависимостями, которые создаются при запуске обычного приложения. –

ответ

1

Источника: Postal Unit Testing

Когда модульное тестирование кода, который использует Postal, вы можете убедиться, что письмо будет отправлено, без фактической отправки его.

Почтовый предоставляет интерфейс IEmailService и реализацию, EmailService, который фактически отправляет электронное письмо.

Предполагая, что вы используете какой-то контейнер IoC, настройте его, чтобы вставить IEmailService в контроллер.

Затем используйте услугу для отправки объектов электронной почты (вместо звонка Email.Send()).

public class HomeController : Controller { 

    readonly IEmailService emailService; 

    public HomeController(IEmailService emailService) { 
     this.emailService = emailService; 
    } 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Contact(EmailModel email) { 
     if(ModelState.IsValid) { 
      emailService.Send(email); 
      ViewBag.Send = true; 
      ModelState.Clear(); 
     } 
     return View(email); 
    } 
} 

Тест этот контроллер путем создания макета интерфейса в IEmailService .

[TestClass] 
public class MailTests { 
    [TestMethod] 
    public void MailSendWithRightModel() { 
     //Arrange 
     var mockService = new Mock<IEmailService>(); 
     var controller = new HomeController(mockService.Object); 
     var email = new EmailSetter().GetEmail(); 

     //Act 
     controller.Contact(email); 

     //Assert 
     mockService.Verify(m => m.Send(email)); 
    } 
} 
+0

Да, я должен был прочитать документацию лучше. Если кто-то будет использовать мой код и этот код ответа: var email = EmailSetter.GetEmail(); следует изменить на EmailModel email = (новый EmailSetter()). GetEmail(); –

+1

Мысль была статическим методом фабрики. исправлено. – Nkosi