问题
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