I am just writing my first unit test to simply test the index of my home controller.
There is a hell of a lot of interfaces I have to mock in order to run this test.
Has anybody any clues how to cut down the amount of code I will need to write.
So far I have this in my TestFixtureSetUp:
#region
protected
MockRepository _mockRepository;
protected
IWindsorContainer _container;
protected
IControllerFactory _controllerFactory;
protected
IHttpContext _mockContext;
protected
RequestContext _context;
protected
RouteData _routeData;
protected
IViewFactory _mockViewFactory;
#endregion
[
TestFixtureSetUp]
public void StartUp()
{
if (_container !=
null)
return;
log4net.Config.XmlConfigurator.Configure();
_mockRepository =
new
MockRepository();
_container = new
WindsorContainer();
_mockContext = _mockRepository.DynamicMock<
IHttpContext>();
MockApplication application =
new MockApplication(_container);
Expect.Call(_mockContext.ApplicationInstance).Return(application);
_routeData = new
RouteData();_context =
new RequestContext(_mockContext, _routeData);
_mockRepository.ReplayAll();
_mockViewFactory = _mockRepository.DynamicMock<
IViewFactory>();
_controllerFactory = new
WindsorControllerFactory();
I happen to know a little bit of Russian, the title says "ASP.NET MVC - when it all looks good only at first sight" [:)]
If we are resolved to use mocks at all costs, that's without no doubt brilliant solution. But subclass seems very clean and simple approach to me, I use it all the time and feel very comfortable. A matter of taste.
M
Writing software would be a lot easier if it weren't for customers
Is Haack implying partial mocking for controllers will work in the next CTP?
I really prefer partial mocks cos they involve less coding, the subclass pattern requires too much duplicated code for each testable controller, it's a bit annoying.
In the end I created my own mock class implentations for the HttpApplication, IHttpContext, IHttpRequest, IHttpResponse, IHttpServerUtility and IHttpSessionState.
I think this better than having to mock everything.
It gets messy when you have to it comes to replaying and verifying.
Maybe the framework could provide these mock implementations?
dagda2
0 Points
28 Posts
Testability and mocking
Jan 08, 2008 02:15 PM|LINK
Hi all,
I am just writing my first unit test to simply test the index of my home controller.
There is a hell of a lot of interfaces I have to mock in order to run this test.
Has anybody any clues how to cut down the amount of code I will need to write.
So far I have this in my TestFixtureSetUp:
#region
protected
MockRepository _mockRepository;protected
IWindsorContainer _container;protected
IControllerFactory _controllerFactory;protected
IHttpContext _mockContext;protected
RequestContext _context;protected
RouteData _routeData;protected
IViewFactory _mockViewFactory;#endregion
[
TestFixtureSetUp] public void StartUp(){
if (_container != null) return; log4net.Config.XmlConfigurator.Configure();_mockRepository =
new MockRepository(); _container = new WindsorContainer();_mockContext = _mockRepository.DynamicMock<
IHttpContext>(); MockApplication application = new MockApplication(_container); Expect.Call(_mockContext.ApplicationInstance).Return(application); _routeData = new RouteData();_context = new RequestContext(_mockContext, _routeData);_mockRepository.ReplayAll();
_mockViewFactory = _mockRepository.DynamicMock<
IViewFactory>(); _controllerFactory = new WindsorControllerFactory();}
And hen in my test I have:
[
Test] public void IndexTest(){
HomeController homeController =(
HomeController) _controllerFactory.CreateController(_context, typeof (HomeController)); ControllerContext contextMock = new ControllerContext(_context, homeController); IView mockView = _mockRepository.DynamicMock<IView>(); Expect.Call(_mockViewFactory.CreateView(contextMock, "Index", string.Empty, homeController.ViewData)).Return(mockView);
Expect.Call(delegate { mockView.RenderView(null); }).IgnoreArguments();_mockRepository.ReplayAll();
homeController.ControllerContext = contextMock;
homeController.ViewFactory = _mockViewFactory;
homeController.Index();
_mockRepository.VerifyAll();
}
That is a lot of mocking. Obviously I will write helper methods but it is quite a lot of boiler plate to be running each time.
Anybody come up with a good answer.
Paul
dagda2
0 Points
28 Posts
Re: Testability and mocking
Jan 08, 2008 03:13 PM|LINK
Actually the test does not work. I get the following error:
Value cannot be null.
Parameter name: tempData
Can anyone show me how I can test RenderView from my controller?
Cheers
Paul
Momcilo
Participant
1477 Points
251 Posts
Re: Testability and mocking
Jan 08, 2008 05:00 PM|LINK
You will need to test against a subclass:
http://haacked.com/archive/2007/12/09/writing-unit-tests-for-controller-actions.aspx
http://haacked.com/archive/2007/12/06/test-specific-subclasses-vs-partial-mocks.aspx
Cheers,
M
dagda2
0 Points
28 Posts
Re: Testability and mocking
Jan 08, 2008 05:19 PM|LINK
I really do not like the subclass idea.
I found everything I need here:
http://yet-another-wannabe.blogspot.com/
The text is in Russian but the code obviously is not.
It sets TempData by using reflection like this:
controller.GetType().GetProperty("TempData").SetValue(controller, new TempDataDictionary(httpContextMock), null);
The code was actually everything I needed.
Let me know what you think of it.
Momcilo
Participant
1477 Points
251 Posts
Re: Testability and mocking
Jan 08, 2008 05:54 PM|LINK
I happen to know a little bit of Russian, the title says "ASP.NET MVC - when it all looks good only at first sight" [:)]
If we are resolved to use mocks at all costs, that's without no doubt brilliant solution. But subclass seems very clean and simple approach to me, I use it all the time and feel very comfortable. A matter of taste.
M
CVertex
Member
147 Points
128 Posts
Re: Testability and mocking
Jan 08, 2008 11:55 PM|LINK
Is Haack implying partial mocking for controllers will work in the next CTP?
I really prefer partial mocks cos they involve less coding, the subclass pattern requires too much duplicated code for each testable controller, it's a bit annoying.
Haacked
Contributor
6901 Points
412 Posts
Re: Testability and mocking
Jan 09, 2008 06:34 AM|LINK
Yes, the next CTP should make the partial mock situation possible. No need for a test-specific subclass pattern.
Senior Program Manager, Microsoft
What wouldn’t you do for a Klondike bar?
dagda2
0 Points
28 Posts
Re: Testability and mocking
Jan 10, 2008 09:35 AM|LINK
In the end I created my own mock class implentations for the HttpApplication, IHttpContext, IHttpRequest, IHttpResponse, IHttpServerUtility and IHttpSessionState.
I think this better than having to mock everything.
It gets messy when you have to it comes to replaying and verifying.
Maybe the framework could provide these mock implementations?