smsohan / MvcMailer

A Mailer for ASP.Net MVC that forms the Email Body using MVC Views (Razor etc.) following Ruby on Rails ActionMailer style
MIT License
584 stars 178 forks source link

Wiki unit test example doesn't work/incomplete #20

Closed daniel-sim closed 13 years ago

daniel-sim commented 13 years ago

I'm trying to unit test a mailer (outside of a controller) using the example on the wiki. But it comes up with the good old httpcontext is null exception.

This guy is having the same problem

http://stackoverflow.com/questions/6080658/mvcmailer-unit-tests-system-argumentnullexception-httpcontext-cannot-be-null/6526006#6526006

Are we missing something?

smsohan commented 13 years ago

Did you set IsTestModeEnabled on your mailer?

Sohan http://smsohan.com skype:smsohan | gtalk:sohan39 | cell: 403-714-2673

On Wed, Jun 29, 2011 at 1:21 PM, daniel-sim < reply@reply.github.com>wrote:

I'm trying to unit test a mailer (outside of a controller) using the example on the wiki. But it comes up with the good old httpcontext is null exception.

This guy is having the same problem

http://stackoverflow.com/questions/6080658/mvcmailer-unit-tests-system-argumentnullexception-httpcontext-cannot-be-null/6526006#6526006

Are we missing something?

Reply to this email directly or view it on GitHub: https://github.com/smsohan/MvcMailer/issues/20

daniel-sim commented 13 years ago

I've tried a couple of things...

System.ArgumentNullException: Value cannot be null. Parameter name: httpContext

for

[TestMethod]
        public void Test_WelcomeMessage()
        {
            //Arrange
            var _mailer = new Mock<UserMailer>();
            _mailer.Setup(x => x.PopulateBody(It.IsAny<MailMessage>(), "Welcome", null));
            _mailer.CallBase = true;

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

            //Assert
        }

but with test mode the mailmessage itself is mocked, which isn't what I'm looking for:

[TestMethod]
        public void Test_WelcomeMessageTestMode()
        {
            //Arrange
            var _mailer = new Mock<UserMailer>();
            MailerBase.IsTestModeEnabled = true;

            var mailMessage = new MailMessage();
            _mailer.Setup(userMailer => userMailer.Welcome()).Returns(mailMessage);

            //Act
            var result = _mailer.Object.Welcome();

            //Assert
        }

I want to invoke the actual method to build a mailmessage from the view

public virtual MailMessage Welcome()
        {
            var mailMessage = new MailMessage { Subject = "Welcome to MvcMailer" };

            mailMessage.To.Add("sohan39@example.com");
            ViewBag.Name = "Sohan";
            PopulateBody(mailMessage, viewName: "Welcome");

            return mailMessage;
        }

Is it possible to unit test building of the mailmessage from a view, without a controller?

D

daniel-sim commented 13 years ago

Looks like I'll have to build a test harness for this

smsohan commented 13 years ago

That would be cool!

Sohan http://smsohan.com skype:smsohan | gtalk:sohan39 | cell: 403-714-2673

On Thu, Jun 30, 2011 at 11:50 AM, daniel-sim < reply@reply.github.com>wrote:

Looks like I'll have to build a test harness for this

Reply to this email directly or view it on GitHub: https://github.com/smsohan/MvcMailer/issues/20#issuecomment-1476564

jhappoldt commented 13 years ago

This issue was closed but as far as I can tell not resolved. Can someone update the wiki with the fix if there is one?

daniel-sim commented 13 years ago

As much as I love the concept of MvcMailer, it's hard to unit test all the pieces. The example is indeed incorrect as my comment above. I burned a good week trying to get a good solution together.

In the end I switched to using NVelocity (the Castle Project fork) and http adapters from Solr and can now mock and unit test all the pieces from controller, building email from a template, and sending the mail.

jhappoldt commented 13 years ago

Thanks for the update @daniel-sim. It looks like we need to wait on the 'Sending using a background process' feature if we want to use MVCMailer in our WCF environment.

smsohan commented 13 years ago

The wiki will work fine if you are using Moq. The other mocking libraries won't let you do partial mocking of a class. I am planning to rearrange some methods so that its easier to mock out the dependency on view rendering like you would do on a regular controller action test. On that background job thing, what I found is, its gonna be hard to make the full asp.net stack available without a web context, e.g. config files, url helpers, application events from global asax, handlers etc. I would say it should be easier to just convert the mailer methods to be invoked by a web service, may be RESTful service, so that you can easily invoke them from an offline app, without worrying about loosing your http context and all that crap.

daniel-sim commented 13 years ago

It didn't work for me on Moq. A proj for the test would be helpful if there's one.

smsohan commented 13 years ago

I am gonna make some changes inside the MvcMailer to alleviate this problem altogether by using the IsTestModeEnabled flag and removing dependency on partial mocking. Added this to list of my targets for this weekend.

defcon84 commented 12 years ago

as far as i know, this still isn't resolved, but i posted a workaround here: http://stackoverflow.com/questions/6080658/mvcmailer-unit-tests-system-argumentnullexception-httpcontext-cannot-be-null/6526006#comment11997372_6080658