使用Machine.Specs使用MVC MailerBase测试类时出错

时间:2015-06-26 17:07:56

标签: c# asp.net-mvc unit-testing mspec

当我尝试测试正在调用继承自MVC FindTask的另一个类(NotificationMailer)的类(MailerBase)时,我收到错误。

  

System.ArgumentNullException:值不能为null。   参数名称:httpContext

class FindTask
{
     public void Find()
     {
         notificationMailer.Notify("Some message").Send();
     }
}

我正在尝试验证FindTask来电NotificationMailer::Notify

public class NotificationMailer : MailerBase, INotificationMailer
{
    public NotificationMailer()
    {
        MasterName = "_Layout";
    }

    public virtual MvcMailMessage Notify(string message)
    {
        return Populate(x =>
        {
            x.Subject = "Some Notification";
            x.ViewName = "Notify";
            x.To.Add("testEmail@test.com");
            x.Body = message;
        });
    }
}

错误发生在返回Populate(...)行。

public class FindTaskSpec : WithSubject<FindTask>
{
    Establish context = () =>
    {
        MvcMailMessage mailMessage = new MvcMailMessage();
        The<INotificationMailer>()
            .WhenToldTo(x => x.Notify(Param<string>.IsAnything))
            .Return(mailMessage); 
    };

    Because of = () => Subject.Find();
}

public class when_something_is_found : FindTaskSpec
{
    It should_send_an_email_with_the_found_stuff = () => The<IDeadLinkMailer>()
        .WasToldTo(x => x.Notify(Param<string>.IsAnything))
        .OnlyOnce();
}

我认为Establish上下文(模拟)中的行应该规定如果调用Notify,它应该返回一个新的MVCMailMessage而不通过函数体。

我的问题:

  1. 如何解决此错误并进行测试以确保调用Notify方法?

  2. 为什么Notify的模拟不会阻止测试进入通知的功能体?

  3. 另一方面,我已经尝试过设置 MailerBase.IsTestModeEnabled = true 。这会导致网址错误 - 无效网址:网址为空;

    我已阅读their wiki page on setting up tests for MvcMailer

    我还阅读了几乎所有其他堆栈溢出页面。我认为this链接最有帮助。问题是我不知道如何模仿他们在这个链接中使用Machine.Specifications做什么。

    如果我可以为链接中显示的任一方法创建模拟,我认为我的问题将得到解决。

1 个答案:

答案 0 :(得分:3)

我认为在这种情况下,我很想创建一个FakeNotificationMailer类,方法是从NotificationMailer派生并重写Notify方法并让它返回预先构建的{{ 1}}。这与你的模拟正在做的基本相同,但一切都是明确的。类似的东西:

MvcMailMessage

(我在弄清楚你的依赖是什么时遇到了问题,所以这在黑暗中有点像。)

当然,你必须找到一个可以注入虚假实现的地方(依赖倒置原则)。