【问题标题】:MvcMailer unit tests: System.ArgumentNullException httpContext cannot be nullMvcMailer 单元测试:System.ArgumentNullException httpContext 不能为空
【发布时间】:2011-08-30 03:42:44
【问题描述】:

我无法使用 Visual Studio 测试套件和 Moq 为 MvcMailer 成功运行单元测试。 我已经从 wiki 逐字复制了这个例子,但每次都得到以下异常:

Test method MvcMailerTest.Tests.MailerTest.TestMethod1 threw exception: 
System.ArgumentNullException: Value cannot be null.
Parameter name: httpContext

代码如下:(使用VS单元测试框架-使用nUnit时的错误与示例完全相同)

        //Arrange: Moq out the PopulateBody method
        var _userMailerMock = new Mock<UserMailer>();
        _userMailerMock.Setup(mailer => mailer.PopulateBody(It.IsAny<MailMessage>(), "Welcome", null));            
        _userMailerMock.CallBase = true;

        //Act
        var mailMessage = _userMailerMock.Object.Welcome();

Welcome() 方法中的以下行失败(直接从 wiki 复制):

 PopulateBody(mailMessage, viewName: "Welcome");

维基在这里:https://github.com/smsohan/MvcMailer/wiki/MvcMailer-Step-by-Step-Guide

类似(几乎完全相同)问题:MvcMailer: Can't complete NUnit tests on Razor Views which use Url.Action

有人知道如何解决/解决这个问题吗?链接的问题说我需要模拟我已经完成的 PopulateBody 方法(根据维基)。

【问题讨论】:

  • 这个 issue was reported 给 MVC Mailer 团队,但没有解决就关闭了。有没有人有解决方法/修复?
  • @Josh,不幸的是我还没有找到修复或解决方法。猜猜这个错误是在 MVC 邮件开发人员手中......
  • 一种解决方法是将您的代码更改为:PopulateBody(mailMessage, "Welcome", null); 这将起作用,因为您有一个针对 PopulateBody 重载的模拟设置,而不是它的 2 参数版本..
  • @FilipCornelissen:终于找到了一个可行的解决方案!谢谢队友... :)
  • @FilipCornelissen 您不想发表您的评论作为答案以便我接受吗?

标签: unit-testing asp.net-mvc-3 moq mvcmailer


【解决方案1】:

您可能还需要模拟 HttpContext。您可以通过创建一个 HttpContextBase 模拟对象并将其分配给您的 Controller 对象来做到这一点。

【讨论】:

  • 我现在只是想测试邮件程序,而不是使用邮件程序的控制器(如果这有什么不同的话!)。
【解决方案2】:

我怀疑这是因为您将新的模拟重新分配给 _userMailerMock 变量,因此实际上并未模拟 PopulateBody 方法。

var _userMailerMock = new Mock<UserMailer>();
_userMailerMock.Setup(mailer => mailer.PopulateBody(It.IsAny<MailMessage>(), "Welcome", null));
_userMailerMock.CallBase = true;

取出第二个赋值_userMailerMock = new Mock&lt;UserMailer&gt;();Callbase = true;之前的行

【讨论】:

  • 糟糕,我错误地将代码粘贴到 stackoverflow 中。代码中只有 1 个赋值给 _userMailerMock。仍然得到同样的错误。
【解决方案3】:

一种解决方法是将您的代码更改为:

PopulateBody(mailMessage, "Welcome", null);

这会起作用,因为您有一个针对 PopulateBody 重载的模拟设置,而不是它的 2 参数版本。..

【讨论】:

    【解决方案4】:

    对 Filip 的回答的快速补充,有人可能会觉得有帮助:我正在使用 MvcMailer 包的 4.0 版。我在我的邮件操作中使用Populate(Action&lt;MvcMailMessage&gt; action) 方法,并注意到它使用PopulateBody四个-参数版本:

    // Mvc.Mailer.MailerBase (using ILSpy)
    public virtual MvcMailMessage Populate(Action<MvcMailMessage> action)
    {
        MvcMailMessage mvcMailMessage = new MvcMailMessage();
        action(mvcMailMessage);
    
        // Four parameters! (comment added by me)
        this.PopulateBody(mvcMailMessage, mvcMailMessage.ViewName, mvcMailMessage.MasterName, mvcMailMessage.LinkedResources);
    
        return mvcMailMessage;
    }
    

    因此,我发现使用四个参数设置模拟...

    PopulateBody(mailMessage, "Welcome", "SomeMasterName", null);
    

    ...成功了。

    【讨论】:

    • 谢谢! Wiki 应该更新到新版本。干得好
    猜你喜欢
    • 2019-01-02
    • 2012-06-29
    • 2022-01-09
    • 1970-01-01
    • 2021-08-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    相关资源
    最近更新 更多