2013-03-18 2 views
1

Я пытаюсь создать Unit Test для кода, использующего ActionMailer, после того, как я написал тест, я получил ошибку System.ArgumentNullException для параметра httpContext.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

возможно дубликат [? Как дразнить HttpContext в ASP.NET MVC с помощью Moq] (HTTP : //stackoverflow.com/questions/1452418/how-do-i-mock-the-httpcontext-in-asp-net-mvc-using-moq) –

+0

Я связал его и все еще получаю ошибку ^^ См. обновление , –

ответ

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>()); 
+0

Это не работает. вызов MailerBase.Email имеет зависимость от HttpContext –