I am setting the thread culture to the culture sent via a cookie on the HttpRequest in the initialize method of a base controller I have created. I now want to create a unit test for this functionality.
In the test I have created a mock HttpContext and added the Cookie. Using this and a routeData helper, I create a RequestContext. Then I create a new controller and call Execute on it passing in the RequestContext.
I first hit a problem regarding TempData and SessionState, which I have fixed by setting the TempData and creating an EmptyTempDataProvider on the controller.
Then I had a problem with the VirtualPathProviderViewengine, which I fixed by creating a VoidActionInvoker.
Is this the best way to test the initialize method? Any doing anything similar and willing to share some code?
Thanks, Jon
namespace MyApp.UnitTests {
[TestClass]
public class ControllerTests {
[TestInitialize]
public void Setup() {
RouteTable.Routes.Clear();
MyApp.MvcApplication.RegisterRoutes(RouteTable.Routes);
}
[TestMethod]
public void Thread_culture_should_be_set_to_cookie_culture() {
// Arrange
var context = HttpMockHelper.FakeHttpContext();
context.Request.Cookies.Add(new HttpCookie(CultureService.CookieName, "nl-NL"));
var reqContext = new RequestContext(context, "~/Home/Landing".Route());
var controller = new HomeController {
TempData = new TempDataDictionary(),
TempDataProvider = new EmptyTempDataProvider(),
ActionInvoker = new VoidActionInvoker()
};
// Act
(controller as IController).Execute(reqContext);
// Assert
Assert.AreEqual("nl-NL", Thread.CurrentThread.CurrentCulture.Name);
}
}
internal class VoidActionInvoker : ControllerActionInvoker {
protected override ActionExecutedContext InvokeActionMethodWithFilters(System.Reflection.MethodInfo methodInfo, IDictionary<string, object> parameters, IList<IActionFilter> filters) {
return new ActionExecutedContext(this.ControllerContext, false, null);
}
protected override void InvokeActionResult(ActionResult actionResult) {
}
}
internal class EmptyTempDataProvider : ITempDataProvider {
public void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values) {
}
public IDictionary<string, object> LoadTempData(ControllerContext controllerContext) {
return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
}
}
}