I've seen people testing that RenderView is called by a controller by inheriting into a "testable" controller. Madness!
RenderView is just a convenience method that calls to IViewEngine, so why not just test expectations on that with a mock? We basically want to test that the correct ViewContext is sent to the RenderView method of the view engine.
This is my test:
[TestFixture]public class HomeControllerTests : ControllerTestsBase<HomeController>{ public override HomeController CreateController() { return new HomeController(); }
[Test] public void Renders_Index() { var render = ExpectRenderView();
Controller.Index();
Assert.That(render.Data.ViewName, Is.EqualTo("Index")); }}
I don't think we can get more straight forward than that!
This is my test base class:(I'm using Moq as the mock framework.)
public abstract class ControllerTestsBase<T> where T : Controller{ public T Controller; public Mock<IViewEngine> ViewEngine;
[SetUp] public virtual void SetUp() { Controller = CreateController(); ViewEngine = new Mock<IViewEngine>(); Controller.ViewEngine = ViewEngine.Object;
Controller.ControllerContext = new Mock<ControllerContext>(new Mock<HttpContextBase>().Object, new RouteData(), Controller).Object; }
public abstract T CreateController();
public RenderCall<ViewContext> ExpectRenderView() { var render = new RenderCall<ViewContext>(); ViewEngine.Expect(v => v.RenderView(It.IsAny<ViewContext>())) .Callback(new Action<ViewContext>(render.Set)); return render; }}
The RenderCall class provides a place to receive the view context that is passed.
public class RenderCall<T>{ bool _called; T _data;
public T Data { get { if (!_called) throw new InvalidOperationException("View was not rendered."); return _data; } }
public void Set(T data) { _data = data; _called = true; }}
Powered by: newtelligence dasBlog 2.2.8279.16125
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2010, Andrew Davey
E-mail