0

I've been looking at this Stackoverflow question and have the answer implemented. It works all fine and dandy until I get to call HtmlHelper.Partial in my helper method, which is listed below. I know it might not be the best code, but this is until I can refactor more of the app. The error it throws is

Previous method 'ViewContext.get_TempData();' requires a return value or an exception to throw.

Am I missing mocking something, or is there a better way to render a usercontrol?

Edit Ok I did miss something, I didn't call mocks.Replay(). Now have another error which it wants something named controller in routeData...progress.

Edit #2 Clarifying I'm trying to mock the call to HtmlHelper.Partial(partialPath, model), I just want that to return whatever partialPath I send in I suppose, or at least not blowup. I did find this page http://andrevianna.com/blog/?p=8 which was very helpful and I almost got things working. This was helpful as well http://farm-fresh-code.blogspot.com/2009/10/mocking-htmlhelper-class-with.html

 public static string RenderRateDetails(this HtmlHelper html, string partialPath, RatesViewData model, RateDetailType type)
    {

        switch (type)
        {
            case RateDetailType.AR:
                if (model.ExistingRateDetailAR != null)
                    return html.Partial(partialPath, model).ToString();
                break;
            case RateDetailType.AP:
                if (model.ExistingRateDetail != null)
                    return html.Partial(partialPath, model).ToString();
                break;

        }

        return string.Empty;
    }
Community
  • 1
  • 1
nportelli
  • 3,934
  • 7
  • 37
  • 52
  • 1
    Suggested refactoring: you could probably simplify your scenario a bit by using inheritance. If you had a RatesViewDataBaseModel, and a couple of child classes, RatesViewDataAPModel and RatesViewDataARModel, you can perform a test based on the 'is' operator rather than the more complex two-stage test you have at present. – Stewart Ritchie Sep 29 '11 at 11:10
  • That is the idea going forward, but the view model is so large and the controller is so large, I'm not sure of the implications in changing it yet. – nportelli Sep 29 '11 at 12:11
  • You also mentioned having trouble with mocks, what are you actually trying to test here? It might help if we see your unit test. – Stewart Ritchie Sep 29 '11 at 13:15
  • I edited the post to hopefully clarify. I suppose I was trying to test if the page would not blow up if one of the ExistingRates was null. – nportelli Sep 29 '11 at 18:19

2 Answers2

1

I think the example given at 'farm fresh code' is the right way to go, you can't directly mock the HtmlHelper, but you can build an instance where all of it's dependencies are mocked.

When you're code calls html.Partial(partialPath, model).ToString(), the HtmlHelper calls properties and methods on the dependencies that you mocked, and you get errors if these don't return reasonable default values.

In this case it looks like the TemplateData property of the mocked ViewContext object was called, and I imagine it returned null, hence:

Previous method 'ViewContext.get_TempData();' requires a return value or an exception to throw.

Once you mock this property, you should be able to get past this error, but you might need to mock a few more things before you get it all working.

It might save you some time to take a look at the MVC source code to see what gets called in the Partial method. You can get that here http://aspnet.codeplex.com/releases/view/58781.

EDIT

BTW. The TempData property returns a System.Web.Mvc.TempDataDictionary. Mocking the property to return an empty instance of one of those should solve the immediate problem.

Stewart Ritchie
  • 926
  • 7
  • 13
  • Yes, I think it is going to be a combination of both. The first link worked...but only if the partial was called from your mocked view, not if it was called from HtmlHelper. I'll keep playing when I have time. It is a shame it is so difficult to test things, of course this is a lot of testing after the fact on a brownfield app. And I don't know what I'm doing. – nportelli Oct 03 '11 at 12:29
0

Have you considered using Display and Editor templates for your user controls rather than extending HtmlHelper?

I used to do the same thing quite a lot in the early MVC versions, but I have switched almost completely to using templates now.

Stewart Ritchie
  • 926
  • 7
  • 13
  • No, I suppose I don't know what those are, I'm new to both ASP.NET MVC and this application. Can you give a link to an example? I think that is what I want to do, but the model isn't setup for it yet. And I didn't want to make such a change not knowing what will break. – nportelli Sep 29 '11 at 12:22
  • 1
    There's good discussion about deisplay and editor templates here: http://stackoverflow.com/questions/5037580/asp-net-mvc-3-partial-vs-display-template-vs-editor-template – Stewart Ritchie Sep 29 '11 at 12:56