2013-03-18 17 views
1

我想为使用ActionMailer的代码创建单元测试,在我编写测试之后,我得到了httpContext参数的System.ArgumentNullException错误。ActionMailer FakeHttpContext

MailController.cs

new Mailer().Welcome(new WelcomeModel 
{ 
    Name = "sss", 
    Email = model.Email 
}).Deliver(); 

MailControllerTest.cs

var model = new WelcomeInputModel{ Email = "[email protected]" }; 
var result = _controller.SendMail(model); 
Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult)); 

我应该怎么办?

UPDATE,我更新了我的代码:

MailControllerTest.cs

var request = new Mock<HttpRequestBase>(); 
request.Setup(r => r.HttpMethod).Returns("GET"); 
_mockHttoContextBase.Setup(c => c.Request).Returns(request.Object); 

MailController.cs

var controller = new MailController {HttpContextBase = _contextBase}; 
controller.Forgot(new ForgotModel 
{ 
    UserName = membershipUser.UserName, 
    Email = user.Email, 
    Password = membershipUser.ResetPassword() 
}).Deliver(); 

现在,我得到错误: System.Nul lReferenceException:未将对象引用设置为对象的实例。

+0

可能重复的HTTP ://stackoverflow.com/questions/1452418/how-do-i-mock-the-httpcontext-in-asp-net-mvc-using-moq) – 2013-03-18 19:40:54

+0

我绑了它,仍然得到错误^^请参阅更新。 – 2013-03-19 06:54:55

回答

0

你不需要伪造httpcontext,只是打破了你的控制器和ActionMailer之间的依赖关系。我给你写了一些包装。

Mailer.cs

public interface IMailer 
{ 
    void SendMail(string viewName, IEnumerable<string> to, string subject, IEnumerable<string> replayTo); 

    void SendMail(string viewName, object model, IEnumerable<string> to, string subject, 
     IEnumerable<string> replayTo); 

    void SendMail(string viewName, IEnumerable<string> to, string from, string subject, IEnumerable<string> replayTo); 

    void SendMail(string viewName, object model, IEnumerable<string> to, string from, string subject, 
     IEnumerable<string> replayTo); 
} 

public class Mailer : MailerBase, IMailer 
{ 
    public void SendMail(string viewName, IEnumerable<string> to, string subject, 
     IEnumerable<string> replayTo = null) 
    { 
     foreach (var email in to) 
     { 
      To.Add(email); 
     } 
     Subject = subject; 
     if (replayTo != null) 
      foreach (var email in replayTo) 
      { 
       ReplyTo.Add(email); 
      } 

     Email(viewName).Deliver(); 
    } 

    public void SendMail(string viewName, object model, IEnumerable<string> to, string subject, 
     IEnumerable<string> replayTo = null) 
    { 
     foreach (var email in to) 
     { 
      To.Add(email); 
     } 
     Subject = subject; 
     if (replayTo != null) 
      foreach (var email in replayTo) 
      { 
       ReplyTo.Add(email); 
      } 

     Email(viewName, model).Deliver(); 
    } 

    public void SendMail(string viewName, IEnumerable<string> to, string from, string subject, 
     IEnumerable<string> replayTo) 
    { 
     foreach (var email in to) 
     { 
      To.Add(email); 
     } 
     From = from; 
     Subject = subject; 
     if (replayTo != null) 
      foreach (var email in replayTo) 
      { 
       ReplyTo.Add(email); 
      } 

     Email(viewName).Deliver(); 
    } 

    public void SendMail(string viewName, object model, IEnumerable<string> to, string from, string subject, 
     IEnumerable<string> replayTo) 
    { 
     foreach (var email in to) 
     { 
      To.Add(email); 
     } 
     From = from; 
     Subject = subject; 
     if (replayTo != null) 
      foreach (var email in replayTo) 
      { 
       ReplyTo.Add(email); 
      } 

     Email(viewName, model).Deliver(); 
    } 
} 

要使用包装,捆住他使用Ninject或任何你想要的库,并在控制器中使用它。

NinjectWebCommon.cs

_kernel.Bind<IMailer>().To<Mailer>(); 

MailController.cs

private readonly IMailer _mailer; 

public MailController(IMailer mailer) { 
    _mailer = mailer; 
} 

_mailer.SendMail("Forgot", new ForgotModel 
{ 
    UserName = membershipUser.UserName, 
    Email = user.Email, 
    Password = membershipUser.ResetPassword() 
}, new List<string> { model.Email }, _myEmail, "Your password", new List<string>()); 
的[?我如何使用嘲笑起订量在ASP.NET MVC的HttpContext(
+0

这不起作用。调用MailerBase.Email对HttpContext有依赖性 – 2014-12-27 17:09:23