MvcMailer unit tests: System.ArgumentNullException httpContext cannot be null

荒凉一梦 提交于 2019-11-30 04:12:31

问题


I cannot successfully run unit tests for MvcMailer using the visual studio test suite and Moq. I have copied the example from the wiki word for word but get the following exception every time:

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

Code is as follows: (Using the VS unit test framework - exact same error when using nUnit as in the example)

        //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();

Fails on the following line in the Welcome() method (copied straight out of the wiki):

 PopulateBody(mailMessage, viewName: "Welcome");

The wiki is here: https://github.com/smsohan/MvcMailer/wiki/MvcMailer-Step-by-Step-Guide

Similar (almost exactly the same) Question: MvcMailer: Can't complete NUnit tests on Razor Views which use Url.Action

Anyone know how to fix/get around this? The linked question says I need to mock out the PopulateBody method which I have done (as per wiki).


回答1:


a workaround is to change your code to this:

PopulateBody(mailMessage, "Welcome", null);

This will work because you have a mock setup for that overload of PopulateBody and not for the 2 parameter version of it..




回答2:


A quick addition to Filip's answer that somebody might find helpful: I am using version 4.0 of the MvcMailer package. I was using the Populate(Action<MvcMailMessage> action) method inside my mailer actions and noticed that it uses a four-parameter version of 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;
}

As such, I found that setting up the mock with four parameters...

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

...did the trick.




回答3:


You probably need to mock HttpContext too. You can do this by creating a HttpContextBase mock object and assign it to your Controller object.




回答4:


I suspect it is due to that you are reassigning a new mock to the _userMailerMock variable and therefore not actually mocking the PopulateBody method.

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

Take out the second assignment _userMailerMock = new Mock<UserMailer>(); the line before Callbase = true;



来源:https://stackoverflow.com/questions/6080658/mvcmailer-unit-tests-system-argumentnullexception-httpcontext-cannot-be-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!