使用 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 没有 运行 通过函数的主体。
我的问题:
如何解决此错误并进行测试以确保调用了 Notify 方法?
为什么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;
}
}
(我在弄清楚你的依赖项是什么时遇到了问题,所以这有点摸不着头脑)。
当然你必须找到可以注入你的假实现的地方(依赖倒置原则)。
我在尝试测试正在调用另一个继承的 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 没有 运行 通过函数的主体。
我的问题:
如何解决此错误并进行测试以确保调用了 Notify 方法?
为什么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;
}
}
(我在弄清楚你的依赖项是什么时遇到了问题,所以这有点摸不着头脑)。
当然你必须找到可以注入你的假实现的地方(依赖倒置原则)。