使用邮政和最小起订量进行单元测试邮件发送
Unit-testing mail sending with postal and moq
System.ArgumentNullException
从 System.Web.HttpBrowserCapabilities
构造函数中抛出,当 mail.Send()
从测试调用时。它需要 httpBrowserCapabilities
参数。
我用过的代码:
电子邮件模型:
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(".+@.+", 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
单元测试:
public class EmailSetter
{
public const string DefaultName = "NameTest";
public const string DefaultEmail = "EmailTest@domaintest.test";
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);
}
我尝试过的(单元测试方法):
通过 new
BrowserCapabilitiesFactory
创建 new HttpBrowserCapabilities
用 HttpBrowserCapabilities
创建 new
HttpBrowserCapabilitiesWrapper
对象
有什么想法可以让代码不抛出异常吗? (即让当前的 HttpBrowserCapabilitiesWrapper 获得现有的 HttpBrowserCapabilities):)
When unit testing code that uses Postal, you may want to verify that
an email would be sent, without actual sending it.
Postal provides an interface IEmailService
and an implementation,
EmailService
, which actually sends email.
Assuming you use some kind of IoC container, configure it to inject an
IEmailService
into your controller.
Then use the service to send email objects (instead of calling
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);
}
}
Test this controller by creating a mock of the IEmailService
interface.
[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));
}
}
System.ArgumentNullException
从 System.Web.HttpBrowserCapabilities
构造函数中抛出,当 mail.Send()
从测试调用时。它需要 httpBrowserCapabilities
参数。
我用过的代码:
电子邮件模型:
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(".+@.+", 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
单元测试:
public class EmailSetter
{
public const string DefaultName = "NameTest";
public const string DefaultEmail = "EmailTest@domaintest.test";
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);
}
我尝试过的(单元测试方法):
通过
new BrowserCapabilitiesFactory
创建new HttpBrowserCapabilities
用
HttpBrowserCapabilities
创建new HttpBrowserCapabilitiesWrapper
对象
有什么想法可以让代码不抛出异常吗? (即让当前的 HttpBrowserCapabilitiesWrapper 获得现有的 HttpBrowserCapabilities):)
When unit testing code that uses Postal, you may want to verify that an email would be sent, without actual sending it.
Postal provides an interface
IEmailService
and an implementation,EmailService
, which actually sends email.Assuming you use some kind of IoC container, configure it to inject an
IEmailService
into your controller.Then use the service to send email objects (instead of calling
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);
}
}
Test this controller by creating a mock of the
IEmailService
interface.
[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));
}
}