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

Error when using Machine.Specs to test class using MVC MailerBase

我在尝试测试正在调用另一个继承的 class (NotificationMailer) 的 class (FindTask) 时收到错误消息来自 MVC MailerBase.

System.ArgumentNullException: Value cannot be null. Parameter name: 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;
        });
    }
}

错误在 return 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 context(模拟)中的行应该规定如果调用 Notify,它应该 return 一个新的 MVCMailMessage 没有 运行 通过函数的主体。

我的问题:

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

  2. 为什么Notify的mock没有阻止测试进入notify的函数体?

附带说明一下,我已经尝试设置 MailerBase.IsTestModeEnabled = true。这会导致 Url 错误 - Invalid Url: The Url is Empty;

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

我还阅读了关于此的几乎所有其他堆栈溢出页面。我认为 this link 最有帮助。问题是我不知道如何模仿他们在link和Machine.Specifications.

中所做的事情

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

我认为在这种情况下,我很想通过从 NotificationMailer 派生并覆盖 Notify 方法并让它 return 预建 MvcMailMessage。这与您的模拟所做的基本相同,但一切都是明确的。类似于:

public class FakeNotificationMailer : MailerBase, INotificationMailer
    {
    MvcMailMessage preBuiltMessage;
    public NotificationMailer(MvcMailMessage result)
        {
        preBuiltMessage = result;
        }

    public virtual MvcMailMessage Notify(string message)
        {
        return preBuiltMessage;
        }
    }

(我在弄清楚你的依赖项是什么时遇到了问题,所以这有点摸不着头脑)。

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