0

I'm trying to mock an ASP.NET MVC2 Controller using Moq but I get an error because i'm trying to mock an non-overridable property. How should I be doing this, please?

NOTE: the controller I'm trying to mock up is the (abstract) ASP.NET MVC2 Controller ... not a custom controller. Why? I'm trying to test some custom controller extensions I have made. I don't actually have a custom controller class.

Code:

// My own test helper magic shiz.
httpContextBaseMock = MockHelpers.GetAnHttpContextBaseMock();

controllerContextMock = new Mock<ControllerContext>();
controllerContextMock.Setup(x => x.HttpContext)
    .Returns(httpContextBaseMock.Object);

controllerMock = new Mock<Controller>();
controllerMock.SetupGet(x => x.RouteData)
    .Returns(RestMockHelpers.MockRouteData().Object);

That last line fails with...

System.ArgumentException : Invalid setup on a non-overridable member: x => x.RouteData

So then I thought, I shouldn't be mocking the controllerContext, but just creating an instance of it.. like what REA_ANDREW did in his SO question ...

var controllerContext = new ControllerContext(_httpContextBaseMock.Object, 
    new RouteData(), new Mock<ControllerBase>().Object);

var controller = new Controller(); <-- Cannot do this.
                                       Controller class is abstract.

So i'm not sure if I need to make my own fake controller class, in some test helper utility that does nothing, but just inherits from Controller. Then instantiate that.

But I feel that it should be all done using mock's, instead of starting out with some, then making some instances...

I'm so confused :(


Update:

I was asked to explain what code i'm trying to test. I've got a custom ViewResult i've made and the constructor set a single string property. I'm just making sure that property is set.

// Act.
var myResult = new MyResult(controllerMock.Object);

// Assert.
Assert.NotNull(myResult);
Assert.AreEqual("controllerName", myResult.ControllerName);
Community
  • 1
  • 1
Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
  • Could you show the code you are trying to test? Maybe there's an easier method. – Darin Dimitrov Jun 23 '10 at 06:28
  • Why not create a dummy controller class and use that for testing in stead of trying to mock it? – Marnix van Valen Jun 23 '10 at 07:27
  • That's my question, Marnix. What's good practice, here? I feel that creating a dummy controller 'smells bad' .. and wanted to see what other people have done. – Pure.Krome Jun 23 '10 at 08:32
  • I don't see why creating a dummy controller would be a code smell. A mock is in fact a dynamically created dummy class. I've had to resort to dummy classes in some instances where overriding properties was not an option. I do tend to keep the dummy class with the test code (e.g. private class) to prevent maintenance issues. – Marnix van Valen Jun 23 '10 at 08:52
  • Agreed - i keep them private, in the same file too. I've done it before - i was just curious to see if there's other ways to do it OR if i've missed something. – Pure.Krome Jun 23 '10 at 11:40

1 Answers1

0

For tests, I create a test class controller inside the test class like:

protected class TestController : Controller { }

And then I have an isolated test class that I can use for the tests. Then you can use this TestController instance.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257