// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.IO; using System.Reflection; using System.Security.Principal; using System.Text; using System.Web.Mvc.Async; using System.Web.Profile; using System.Web.Routing; using System.Web.TestUtil; using Microsoft.Web.UnitTestUtil; using Moq; using Moq.Protected; using Xunit; using Assert = Microsoft.TestCommon.AssertEx; namespace System.Web.Mvc.Test { public class ControllerTest { [Fact] public void ActionInvokerProperty() { // Arrange Controller controller = new EmptyController(); // Act & Assert MemberHelper.TestPropertyWithDefaultInstance(controller, "ActionInvoker", new ControllerActionInvoker()); } [Fact] public void ContentWithContentString() { // Arrange Controller controller = new EmptyController(); string content = "Some content"; // Act ContentResult result = controller.Content(content); // Assert Assert.Equal(content, result.Content); } [Fact] public void ContentWithContentStringAndContentType() { // Arrange Controller controller = new EmptyController(); string content = "Some content"; string contentType = "Some content type"; // Act ContentResult result = controller.Content(content, contentType); // Assert Assert.Equal(content, result.Content); Assert.Equal(contentType, result.ContentType); } [Fact] public void ContentWithContentStringAndContentTypeAndEncoding() { // Arrange Controller controller = new EmptyController(); string content = "Some content"; string contentType = "Some content type"; Encoding contentEncoding = Encoding.UTF8; // Act ContentResult result = controller.Content(content, contentType, contentEncoding); // Assert Assert.Equal(content, result.Content); Assert.Equal(contentType, result.ContentType); Assert.Same(contentEncoding, result.ContentEncoding); } [Fact] public void ContextProperty() { var controller = new EmptyController(); MemberHelper.TestPropertyValue(controller, "ControllerContext", new Mock().Object); } [Fact] public void HttpContextProperty() { var c = new EmptyController(); Assert.Null(c.HttpContext); Mock mockHttpContext = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext).Returns(mockHttpContext.Object); c.ControllerContext = mockControllerContext.Object; Assert.Equal(mockHttpContext.Object, c.HttpContext); } [Fact] public void HttpNotFound() { // Arrange var c = new EmptyController(); // Act HttpNotFoundResult result = c.HttpNotFound(); // Assert Assert.NotNull(result); Assert.Null(result.StatusDescription); Assert.Equal(404, result.StatusCode); } [Fact] public void HttpNotFoundWithNullStatusDescription() { // Arrange var c = new EmptyController(); // Act HttpNotFoundResult result = c.HttpNotFound(statusDescription: null); // Assert Assert.NotNull(result); Assert.Null(result.StatusDescription); Assert.Equal(404, result.StatusCode); } [Fact] public void HttpNotFoundWithStatusDescription() { // Arrange var c = new EmptyController(); // Act HttpNotFoundResult result = c.HttpNotFound(statusDescription: "I lost it"); // Assert Assert.NotNull(result); Assert.Equal("I lost it", result.StatusDescription); Assert.Equal(404, result.StatusCode); } [Fact] public void ModelStateProperty() { // Arrange Controller controller = new EmptyController(); // Act & assert Assert.Same(controller.ViewData.ModelState, controller.ModelState); } [Fact] public void ProfileProperty() { var c = new EmptyController(); Assert.Null(c.Profile); Mock mockProfile = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext.Profile).Returns(mockProfile.Object); c.ControllerContext = mockControllerContext.Object; Assert.Equal(mockProfile.Object, c.Profile); } [Fact] public void RequestProperty() { var c = new EmptyController(); Assert.Null(c.Request); Mock mockHttpRequest = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext.Request).Returns(mockHttpRequest.Object); c.ControllerContext = mockControllerContext.Object; Assert.Equal(mockHttpRequest.Object, c.Request); } [Fact] public void ResponseProperty() { var c = new EmptyController(); Assert.Null(c.Request); Mock mockHttpResponse = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext.Response).Returns(mockHttpResponse.Object); c.ControllerContext = mockControllerContext.Object; Assert.Equal(mockHttpResponse.Object, c.Response); } [Fact] public void ServerProperty() { var c = new EmptyController(); Assert.Null(c.Request); Mock mockServerUtility = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext.Server).Returns(mockServerUtility.Object); c.ControllerContext = mockControllerContext.Object; Assert.Equal(mockServerUtility.Object, c.Server); } [Fact] public void SessionProperty() { var c = new EmptyController(); Assert.Null(c.Request); Mock mockSessionState = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext.Session).Returns(mockSessionState.Object); c.ControllerContext = mockControllerContext.Object; Assert.Same(mockSessionState.Object, c.Session); } [Fact] public void UrlProperty() { // Arrange EmptyController controller = new EmptyController(); RequestContext requestContext = new RequestContext(new Mock().Object, new RouteData()); // Act controller.PublicInitialize(requestContext); // Assert Assert.NotNull(controller.Url); } [Fact] public void UserProperty() { var c = new EmptyController(); Assert.Null(c.Request); Mock mockUser = new Mock(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.HttpContext.User).Returns(mockUser.Object); c.ControllerContext = mockControllerContext.Object; Assert.Equal(mockUser.Object, c.User); } [Fact] public void RouteDataProperty() { var c = new EmptyController(); Assert.Null(c.Request); RouteData rd = new RouteData(); Mock mockControllerContext = new Mock(); mockControllerContext.Setup(cc => cc.Controller).Returns(c); mockControllerContext.Setup(cc => cc.RouteData).Returns(rd); c.ControllerContext = mockControllerContext.Object; Assert.Equal(rd, c.RouteData); } [Fact] public void ControllerMethodsDoNotHaveNonActionAttribute() { var methods = typeof(Controller).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (var method in methods) { var attrs = method.GetCustomAttributes(typeof(NonActionAttribute), true /* inherit */); Assert.True(attrs.Length == 0, "Methods on the Controller class should not be marked [NonAction]: " + method); } } [Fact] public void DisposeCallsProtectedDisposingMethod() { // Arrange Mock mockController = new Mock(); mockController.Protected().Setup("Dispose", true).Verifiable(); Controller controller = mockController.Object; // Act controller.Dispose(); // Assert mockController.Verify(); } [Fact] public void ExecuteWithUnknownAction() { // Arrange UnknownActionController controller = new UnknownActionController(); // We need a provider since Controller.Execute is called controller.TempDataProvider = new EmptyTempDataProvider(); ControllerContext context = GetControllerContext("Foo"); Mock mockInvoker = new Mock(); mockInvoker.Setup(o => o.InvokeAction(context, "Foo")).Returns(false); controller.ActionInvoker = mockInvoker.Object; // Act ((IController)controller).Execute(context.RequestContext); // Assert Assert.True(controller.WasCalled); } [Fact] public void FileWithContents() { // Arrange EmptyController controller = new EmptyController(); byte[] fileContents = new byte[0]; // Act FileContentResult result = controller.File(fileContents, "someContentType"); // Assert Assert.NotNull(result); Assert.Same(fileContents, result.FileContents); Assert.Equal("someContentType", result.ContentType); Assert.Equal(String.Empty, result.FileDownloadName); } [Fact] public void FileWithContentsAndFileDownloadName() { // Arrange EmptyController controller = new EmptyController(); byte[] fileContents = new byte[0]; // Act FileContentResult result = controller.File(fileContents, "someContentType", "someDownloadName"); // Assert Assert.NotNull(result); Assert.Same(fileContents, result.FileContents); Assert.Equal("someContentType", result.ContentType); Assert.Equal("someDownloadName", result.FileDownloadName); } [Fact] public void FileWithPath() { // Arrange EmptyController controller = new EmptyController(); // Act FilePathResult result = controller.File("somePath", "someContentType"); // Assert Assert.NotNull(result); Assert.Equal("somePath", result.FileName); Assert.Equal("someContentType", result.ContentType); Assert.Equal(String.Empty, result.FileDownloadName); } [Fact] public void FileWithPathAndFileDownloadName() { // Arrange EmptyController controller = new EmptyController(); // Act FilePathResult result = controller.File("somePath", "someContentType", "someDownloadName"); // Assert Assert.NotNull(result); Assert.Equal("somePath", result.FileName); Assert.Equal("someContentType", result.ContentType); Assert.Equal("someDownloadName", result.FileDownloadName); } [Fact] public void FileWithStream() { // Arrange EmptyController controller = new EmptyController(); Stream fileStream = Stream.Null; // Act FileStreamResult result = controller.File(fileStream, "someContentType"); // Assert Assert.NotNull(result); Assert.Same(fileStream, result.FileStream); Assert.Equal("someContentType", result.ContentType); Assert.Equal(String.Empty, result.FileDownloadName); } [Fact] public void FileWithStreamAndFileDownloadName() { // Arrange EmptyController controller = new EmptyController(); Stream fileStream = Stream.Null; // Act FileStreamResult result = controller.File(fileStream, "someContentType", "someDownloadName"); // Assert Assert.NotNull(result); Assert.Same(fileStream, result.FileStream); Assert.Equal("someContentType", result.ContentType); Assert.Equal("someDownloadName", result.FileDownloadName); } [Fact] public void HandleUnknownActionThrows() { var controller = new EmptyController(); Assert.Throws( delegate { controller.HandleUnknownAction("UnknownAction"); }, "A public action method 'UnknownAction' was not found on controller 'System.Web.Mvc.Test.ControllerTest+EmptyController'."); } [Fact] public void JavaScript() { // Arrange Controller controller = GetEmptyController(); string script = "alert('foo');"; // Act JavaScriptResult result = controller.JavaScript(script); // Assert Assert.Equal(script, result.Script); } [Fact] public void PartialView() { // Arrange Controller controller = GetEmptyController(); // Act PartialViewResult result = controller.PartialView(); // Assert Assert.Same(controller.TempData, result.TempData); Assert.Same(controller.ViewData, result.ViewData); Assert.Same(ViewEngines.Engines, result.ViewEngineCollection); } [Fact] public void PartialView_Model() { // Arrange Controller controller = GetEmptyController(); object model = new object(); // Act PartialViewResult result = controller.PartialView(model); // Assert Assert.Same(model, result.ViewData.Model); Assert.Same(controller.TempData, result.TempData); Assert.Same(controller.ViewData, result.ViewData); } [Fact] public void PartialView_ViewName() { // Arrange Controller controller = GetEmptyController(); // Act PartialViewResult result = controller.PartialView("Some partial view"); // Assert Assert.Equal("Some partial view", result.ViewName); Assert.Same(controller.TempData, result.TempData); Assert.Same(controller.ViewData, result.ViewData); } [Fact] public void PartialView_ViewName_Model() { // Arrange Controller controller = GetEmptyController(); object model = new object(); // Act PartialViewResult result = controller.PartialView("Some partial view", model); // Assert Assert.Equal("Some partial view", result.ViewName); Assert.Same(model, result.ViewData.Model); Assert.Same(controller.TempData, result.TempData); Assert.Same(controller.ViewData, result.ViewData); } [Fact] public void PartialView_ViewEngineCollection() { // Arrange Controller controller = GetEmptyController(); ViewEngineCollection viewEngines = new ViewEngineCollection(); controller.ViewEngineCollection = viewEngines; // Act PartialViewResult result = controller.PartialView(); // Assert Assert.Same(viewEngines, result.ViewEngineCollection); } [Fact] public void RedirectToActionClonesRouteValueDictionary() { // The RedirectToAction() method should clone the provided dictionary, then operate on the clone. // The original dictionary should remain unmodified throughout the helper's execution. // Arrange Controller controller = GetEmptyController(); RouteValueDictionary values = new RouteValueDictionary(new { Action = "SomeAction", Controller = "SomeController" }); // Act controller.RedirectToAction("SomeOtherAction", "SomeOtherController", values); // Assert Assert.Equal(2, values.Count); Assert.Equal("SomeAction", values["action"]); Assert.Equal("SomeController", values["controller"]); } [Fact] public void RedirectToActionOverwritesActionDictionaryKey() { // Arrange Controller controller = GetEmptyController(); object values = new { Action = "SomeAction" }; // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", values); RouteValueDictionary newValues = result.RouteValues; // Assert Assert.Equal("SomeOtherAction", newValues["action"]); } [Fact] public void RedirectToActionOverwritesControllerDictionaryKeyIfSpecified() { // Arrange Controller controller = GetEmptyController(); object values = new { Action = "SomeAction", Controller = "SomeController" }; // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", "SomeOtherController", values); RouteValueDictionary newValues = result.RouteValues; // Assert Assert.Equal("SomeOtherController", newValues["controller"]); } [Fact] public void RedirectToActionPreservesControllerDictionaryKeyIfNotSpecified() { // Arrange Controller controller = GetEmptyController(); object values = new { Controller = "SomeController" }; // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", values); RouteValueDictionary newValues = result.RouteValues; // Assert Assert.Equal("SomeController", newValues["controller"]); } [Fact] public void RedirectToActionWithActionName() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction"); // Assert Assert.Equal("", result.RouteName); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionWithActionNameAndControllerName() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", "SomeOtherController"); // Assert Assert.Equal("", result.RouteName); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("SomeOtherController", result.RouteValues["controller"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionWithActionNameAndControllerNameAndValuesDictionary() { // Arrange Controller controller = GetEmptyController(); RouteValueDictionary values = new RouteValueDictionary(new { Foo = "SomeFoo" }); // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", "SomeOtherController", values); // Assert Assert.Equal("", result.RouteName); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("SomeOtherController", result.RouteValues["controller"]); Assert.Equal("SomeFoo", result.RouteValues["foo"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionWithActionNameAndControllerNameAndValuesObject() { // Arrange Controller controller = GetEmptyController(); object values = new { Foo = "SomeFoo" }; // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", "SomeOtherController", values); // Assert Assert.Equal("", result.RouteName); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("SomeOtherController", result.RouteValues["controller"]); Assert.Equal("SomeFoo", result.RouteValues["foo"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionSelectsCurrentControllerByDefault() { // Arrange TestRouteController controller = new TestRouteController(); controller.ControllerContext = GetControllerContext("SomeAction", "TestRoute"); // Act RedirectToRouteResult route = controller.Index() as RedirectToRouteResult; // Assert Assert.Equal("SomeAction", route.RouteValues["action"]); Assert.Equal("TestRoute", route.RouteValues["controller"]); } [Fact] public void RedirectToActionDictionaryOverridesDefaultControllerName() { // Arrange TestRouteController controller = new TestRouteController(); object values = new { controller = "SomeOtherController" }; controller.ControllerContext = GetControllerContext("SomeAction", "TestRoute"); // Act RedirectToRouteResult route = controller.RedirectToAction("SomeOtherAction", values); // Assert Assert.Equal("SomeOtherAction", route.RouteValues["action"]); Assert.Equal("SomeOtherController", route.RouteValues["controller"]); } [Fact] public void RedirectToActionSimpleOverridesCallLegacyMethod() { // The simple overrides need to call RedirectToAction(string, string, RouteValueDictionary) to maintain backwards compat // Arrange int invocationCount = 0; Mock controllerMock = new Mock(); controllerMock.Setup(c => c.RedirectToAction(It.IsAny(), It.IsAny(), It.IsAny())).Callback(() => { invocationCount++; }); Controller controller = controllerMock.Object; // Act controller.RedirectToAction("SomeAction"); controller.RedirectToAction("SomeAction", (object)null); controller.RedirectToAction("SomeAction", (RouteValueDictionary)null); controller.RedirectToAction("SomeAction", "SomeController"); controller.RedirectToAction("SomeAction", "SomeController", (object)null); // Assert Assert.Equal(5, invocationCount); } [Fact] public void RedirectToActionWithActionNameAndValuesDictionary() { // Arrange Controller controller = GetEmptyController(); RouteValueDictionary values = new RouteValueDictionary(new { Foo = "SomeFoo" }); // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", values); // Assert Assert.Equal("", result.RouteName); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("SomeFoo", result.RouteValues["foo"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionWithActionNameAndValuesObject() { // Arrange Controller controller = GetEmptyController(); object values = new { Foo = "SomeFoo" }; // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", values); // Assert Assert.Equal("", result.RouteName); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("SomeFoo", result.RouteValues["foo"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionWithNullRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToAction("SomeOtherAction", (RouteValueDictionary)null); RouteValueDictionary newValues = result.RouteValues; // Assert Assert.Single(newValues); Assert.Equal("SomeOtherAction", newValues["action"]); Assert.False(result.Permanent); } [Fact] public void RedirectToActionPermanent() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToActionPermanent("SomeOtherAction"); // Assert Assert.True(result.Permanent); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Null(result.RouteValues["controller"]); } [Fact] public void RedirectToActionPermanentWithObjectDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToActionPermanent("SomeOtherAction", controllerName: "SomeController", routeValues: new { foo = "bar" }); // Assert Assert.True(result.Permanent); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("bar", result.RouteValues["foo"]); Assert.Equal("SomeController", result.RouteValues["controller"]); } [Fact] public void RedirectToActionPermanentWithRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToActionPermanent("SomeOtherAction", routeValues: new RouteValueDictionary(new { foo = "bar" })); // Assert Assert.True(result.Permanent); Assert.Equal("SomeOtherAction", result.RouteValues["action"]); Assert.Equal("bar", result.RouteValues["foo"]); } [Fact] public void RedirectToRouteSimpleOverridesCallLegacyMethod() { // The simple overrides need to call RedirectToRoute(string, RouteValueDictionary) to maintain backwards compat // Arrange int invocationCount = 0; Mock controllerMock = new Mock(); controllerMock.Setup(c => c.RedirectToRoute(It.IsAny(), It.IsAny())).Callback(() => { invocationCount++; }); Controller controller = controllerMock.Object; // Act controller.RedirectToRoute("SomeRoute"); controller.RedirectToRoute("SomeRoute", (object)null); controller.RedirectToRoute((object)null); controller.RedirectToRoute((RouteValueDictionary)null); // Assert Assert.Equal(4, invocationCount); } [Fact] public void RedirectToRouteWithNullRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToRoute((RouteValueDictionary)null); // Assert Assert.Empty(result.RouteValues); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithObjectDictionary() { // Arrange Controller controller = GetEmptyController(); var values = new { Foo = "MyFoo" }; // Act RedirectToRouteResult result = controller.RedirectToRoute(values); // Assert Assert.Single(result.RouteValues); Assert.Equal("MyFoo", result.RouteValues["Foo"]); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); RouteValueDictionary values = new RouteValueDictionary() { { "Foo", "MyFoo" } }; // Act RedirectToRouteResult result = controller.RedirectToRoute(values); // Assert Assert.Single(result.RouteValues); Assert.Equal("MyFoo", result.RouteValues["Foo"]); Assert.NotSame(values, result.RouteValues); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithName() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToRoute("foo"); // Assert Assert.Empty(result.RouteValues); Assert.Equal("foo", result.RouteName); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithNameAndNullRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToRoute("foo", (RouteValueDictionary)null); // Assert Assert.Empty(result.RouteValues); Assert.Equal("foo", result.RouteName); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithNullNameAndNullRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToRoute(null, (RouteValueDictionary)null); // Assert Assert.Empty(result.RouteValues); Assert.Equal(String.Empty, result.RouteName); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithNameAndObjectDictionary() { // Arrange Controller controller = GetEmptyController(); var values = new { Foo = "MyFoo" }; // Act RedirectToRouteResult result = controller.RedirectToRoute("foo", values); // Assert Assert.Single(result.RouteValues); Assert.Equal("MyFoo", result.RouteValues["Foo"]); Assert.Equal("foo", result.RouteName); Assert.False(result.Permanent); } [Fact] public void RedirectToRouteWithNameAndRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); RouteValueDictionary values = new RouteValueDictionary() { { "Foo", "MyFoo" } }; // Act RedirectToRouteResult result = controller.RedirectToRoute("foo", values); // Assert Assert.Single(result.RouteValues); Assert.Equal("MyFoo", result.RouteValues["Foo"]); Assert.NotSame(values, result.RouteValues); Assert.Equal("foo", result.RouteName); Assert.False(result.Permanent); } [Fact] public void RedirectToRoutePermanentWithObjectDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToRoutePermanent(routeValues: new { Foo = "Bar" }); // Assert Assert.True(result.Permanent); Assert.Equal("Bar", result.RouteValues["Foo"]); } [Fact] public void RedirectToRoutePermanentWithRouteValueDictionary() { // Arrange Controller controller = GetEmptyController(); // Act RedirectToRouteResult result = controller.RedirectToRoutePermanent(routeValues: new RouteValueDictionary(new { Foo = "Bar" })); // Assert Assert.True(result.Permanent); Assert.Equal("Bar", result.RouteValues["Foo"]); } [Fact] public void RedirectReturnsCorrectActionResult() { // Arrange Controller controller = GetEmptyController(); // Act & Assert var result = controller.Redirect("http://www.contoso.com/"); // Assert Assert.Equal("http://www.contoso.com/", result.Url); Assert.False(result.Permanent); } [Fact] public void RedirectPermanentReturnsCorrectActionResult() { // Arrange Controller controller = GetEmptyController(); // Act & Assert var result = controller.RedirectPermanent("http://www.contoso.com/"); // Assert Assert.Equal("http://www.contoso.com/", result.Url); Assert.True(result.Permanent); } [Fact] public void RedirectWithEmptyUrlThrows() { // Arrange Controller controller = GetEmptyController(); // Act & Assert Assert.ThrowsArgumentNullOrEmpty( delegate { controller.Redirect(String.Empty); }, "url"); } [Fact] public void RedirectPermanentWithEmptyUrlThrows() { // Arrange Controller controller = GetEmptyController(); // Act & Assert Assert.ThrowsArgumentNullOrEmpty( delegate { controller.RedirectPermanent(String.Empty); }, "url"); } [Fact] public void RedirectWithNullUrlThrows() { // Arrange Controller controller = GetEmptyController(); // Act & Assert Assert.ThrowsArgumentNullOrEmpty( delegate { controller.Redirect(url: null); }, "url"); } [Fact] public void RedirectPermanentWithNullUrlThrows() { // Arrange Controller controller = GetEmptyController(); // Act & Assert Assert.ThrowsArgumentNullOrEmpty( delegate { controller.RedirectPermanent(url: null); }, "url"); } [Fact] public void View() { // Arrange Controller controller = GetEmptyController(); // Act ViewResult result = controller.View(); // Assert Assert.Same(controller.ViewData, result.ViewData); Assert.Same(controller.TempData, result.TempData); Assert.Same(ViewEngines.Engines, result.ViewEngineCollection); } [Fact] public void View_Model() { // Arrange Controller controller = GetEmptyController(); object viewItem = new object(); // Act ViewResult result = controller.View(viewItem); // Assert Assert.Same(viewItem, result.ViewData.Model); Assert.Same(controller.TempData, result.TempData); } [Fact] public void View_ViewName() { // Arrange Controller controller = GetEmptyController(); // Act ViewResult result = controller.View("Foo"); // Assert Assert.Equal("Foo", result.ViewName); Assert.Same(controller.ViewData, result.ViewData); Assert.Same(controller.TempData, result.TempData); } [Fact] public void View_ViewName_Model() { // Arrange Controller controller = GetEmptyController(); object viewItem = new object(); // Act ViewResult result = controller.View("Foo", viewItem); // Assert Assert.Equal("Foo", result.ViewName); Assert.Same(viewItem, result.ViewData.Model); Assert.Same(controller.TempData, result.TempData); } [Fact] public void View_ViewName_MasterViewName() { // Arrange Controller controller = GetEmptyController(); // Act ViewResult result = controller.View("Foo", "Bar"); // Assert Assert.Equal("Foo", result.ViewName); Assert.Equal("Bar", result.MasterName); Assert.Same(controller.ViewData, result.ViewData); Assert.Same(controller.TempData, result.TempData); } [Fact] public void View_ViewName_MasterViewName_Model() { // Arrange Controller controller = GetEmptyController(); object viewItem = new object(); // Act ViewResult result = controller.View("Foo", "Bar", viewItem); // Assert Assert.Equal("Foo", result.ViewName); Assert.Equal("Bar", result.MasterName); Assert.Same(viewItem, result.ViewData.Model); Assert.Same(controller.TempData, result.TempData); } [Fact] public void View_View() { // Arrange Controller controller = GetEmptyController(); IView view = new Mock().Object; // Act ViewResult result = controller.View(view); // Assert Assert.Same(result.View, view); Assert.Same(controller.ViewData, result.ViewData); Assert.Same(controller.TempData, result.TempData); } [Fact] public void View_View_Model() { // Arrange Controller controller = GetEmptyController(); IView view = new Mock().Object; object model = new object(); // Act ViewResult result = controller.View(view, model); // Assert Assert.Same(result.View, view); Assert.Same(controller.ViewData, result.ViewData); Assert.Same(controller.TempData, result.TempData); Assert.Same(model, result.ViewData.Model); } [Fact] public void View_ViewEngineCollection() { // Arrange Controller controller = GetEmptyController(); ViewEngineCollection viewEngines = new ViewEngineCollection(); controller.ViewEngineCollection = viewEngines; // Act ViewResult result = controller.View(); // Assert Assert.Same(viewEngines, result.ViewEngineCollection); } internal static void AddRequestParams(Mock requestMock, object paramValues) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(paramValues); foreach (PropertyDescriptor prop in props) { requestMock.Setup(o => o[It.Is(item => String.Equals(prop.Name, item, StringComparison.OrdinalIgnoreCase))]).Returns((string)prop.GetValue(paramValues)); } } [Fact] public void TempDataGreetUserWithNoUserIDRedirects() { // Arrange TempDataHomeController tempDataHomeController = new TempDataHomeController(); // Act RedirectToRouteResult result = tempDataHomeController.GreetUser() as RedirectToRouteResult; RouteValueDictionary values = result.RouteValues; // Assert Assert.True(values.ContainsKey("action")); Assert.Equal("ErrorPage", values["action"]); Assert.Empty(tempDataHomeController.TempData); } [Fact] public void TempDataGreetUserWithUserIDCopiesToViewDataAndRenders() { // Arrange TempDataHomeController tempDataHomeController = new TempDataHomeController(); tempDataHomeController.TempData["UserID"] = "TestUserID"; // Act ViewResult result = tempDataHomeController.GreetUser() as ViewResult; ViewDataDictionary viewData = tempDataHomeController.ViewData; // Assert Assert.Equal("GreetUser", result.ViewName); Assert.NotNull(viewData); Assert.True(viewData.ContainsKey("NewUserID")); Assert.Equal("TestUserID", viewData["NewUserID"]); } [Fact] public void TempDataIndexSavesUserIDAndRedirects() { // Arrange TempDataHomeController tempDataHomeController = new TempDataHomeController(); // Act RedirectToRouteResult result = tempDataHomeController.Index() as RedirectToRouteResult; RouteValueDictionary values = result.RouteValues; // Assert Assert.True(values.ContainsKey("action")); Assert.Equal("GreetUser", values["action"]); Assert.True(tempDataHomeController.TempData.ContainsKey("UserID")); Assert.Equal("user123", tempDataHomeController.TempData["UserID"]); } [Fact] public void TempDataSavedWhenControllerThrows() { // Arrange BrokenController controller = new BrokenController() { ValidateRequest = false }; Mock mockContext = HttpContextHelpers.GetMockHttpContext(); HttpSessionStateBase session = GetEmptySession(); mockContext.Setup(o => o.Session).Returns(session); RouteData rd = new RouteData(); rd.Values.Add("action", "Crash"); controller.ControllerContext = new ControllerContext(mockContext.Object, rd, controller); // Assert Assert.Throws( delegate { ((IController)controller).Execute(controller.ControllerContext.RequestContext); }); Assert.NotEqual(mockContext.Object.Session[SessionStateTempDataProvider.TempDataSessionStateKey], null); TempDataDictionary tempData = new TempDataDictionary(); tempData.Load(controller.ControllerContext, controller.TempDataProvider); Assert.Equal(tempData["Key1"], "Value1"); } [Fact] public void TempDataMovedToPreviousTempDataInDestinationController() { // Arrange Mock mockController = new Mock() { CallBase = true }; Mock mockContext = new Mock(); HttpSessionStateBase session = GetEmptySession(); mockContext.Setup(o => o.Session).Returns(session); mockController.Object.ControllerContext = new ControllerContext(mockContext.Object, new RouteData(), mockController.Object); // Act mockController.Object.TempData.Add("Key", "Value"); mockController.Object.TempData.Save(mockController.Object.ControllerContext, mockController.Object.TempDataProvider); // Assert Assert.True(mockController.Object.TempData.ContainsKey("Key")); Assert.True(mockController.Object.TempData.ContainsValue("Value")); // Instantiate "destination" controller with the same session state and see that it gets the temp data Mock mockDestinationController = new Mock() { CallBase = true }; Mock mockDestinationContext = new Mock(); mockDestinationContext.Setup(o => o.Session).Returns(session); mockDestinationController.Object.ControllerContext = new ControllerContext(mockDestinationContext.Object, new RouteData(), mockDestinationController.Object); mockDestinationController.Object.TempData.Load(mockDestinationController.Object.ControllerContext, mockDestinationController.Object.TempDataProvider); // Assert Assert.True(mockDestinationController.Object.TempData.ContainsKey("Key")); // Act mockDestinationController.Object.TempData["NewKey"] = "NewValue"; Assert.True(mockDestinationController.Object.TempData.ContainsKey("NewKey")); mockDestinationController.Object.TempData.Save(mockDestinationController.Object.ControllerContext, mockDestinationController.Object.TempDataProvider); // Instantiate "second destination" controller with the same session state and see that it gets the temp data Mock mockSecondDestinationController = new Mock() { CallBase = true }; Mock mockSecondDestinationContext = new Mock(); mockSecondDestinationContext.Setup(o => o.Session).Returns(session); mockSecondDestinationController.Object.ControllerContext = new ControllerContext(mockSecondDestinationContext.Object, new RouteData(), mockSecondDestinationController.Object); mockSecondDestinationController.Object.TempData.Load(mockSecondDestinationController.Object.ControllerContext, mockSecondDestinationController.Object.TempDataProvider); // Assert Assert.True(mockSecondDestinationController.Object.TempData.ContainsKey("Key")); Assert.True(mockSecondDestinationController.Object.TempData.ContainsKey("NewKey")); } [Fact] public void TempDataRemovesKeyWhenRead() { // Arrange Mock mockController = new Mock() { CallBase = true }; Mock mockContext = new Mock(); HttpSessionStateBase session = GetEmptySession(); mockContext.Setup(o => o.Session).Returns(session); mockController.Object.ControllerContext = new ControllerContext(mockContext.Object, new RouteData(), mockController.Object); // Act mockController.Object.TempData.Add("Key", "Value"); mockController.Object.TempData.Save(mockController.Object.ControllerContext, mockController.Object.TempDataProvider); // Assert Assert.True(mockController.Object.TempData.ContainsKey("Key")); Assert.True(mockController.Object.TempData.ContainsValue("Value")); // Instantiate "destination" controller with the same session state and see that it gets the temp data Mock mockDestinationController = new Mock() { CallBase = true }; Mock mockDestinationContext = new Mock(); mockDestinationContext.Setup(o => o.Session).Returns(session); mockDestinationController.Object.ControllerContext = new ControllerContext(mockDestinationContext.Object, new RouteData(), mockDestinationController.Object); mockDestinationController.Object.TempData.Load(mockDestinationController.Object.ControllerContext, mockDestinationController.Object.TempDataProvider); // Assert Assert.True(mockDestinationController.Object.TempData.ContainsKey("Key")); // Act object value = mockDestinationController.Object.TempData["Key"]; mockDestinationController.Object.TempData.Save(mockDestinationController.Object.ControllerContext, mockDestinationController.Object.TempDataProvider); // Instantiate "second destination" controller with the same session state and see that it gets the temp data Mock mockSecondDestinationController = new Mock() { CallBase = true }; Mock mockSecondDestinationContext = new Mock(); mockSecondDestinationContext.Setup(o => o.Session).Returns(session); mockSecondDestinationController.Object.ControllerContext = new ControllerContext(mockSecondDestinationContext.Object, new RouteData(), mockSecondDestinationController.Object); mockSecondDestinationController.Object.TempData.Load(mockSecondDestinationController.Object.ControllerContext, mockSecondDestinationController.Object.TempDataProvider); // Assert Assert.False(mockSecondDestinationController.Object.TempData.ContainsKey("Key")); } [Fact] public void TempDataValidForSingleControllerWhenSessionStateDisabled() { // Arrange Mock mockController = new Mock(); Mock mockContext = new Mock(); HttpSessionStateBase session = null; mockContext.Setup(o => o.Session).Returns(session); mockController.Object.ControllerContext = new ControllerContext(mockContext.Object, new RouteData(), mockController.Object); mockController.Object.TempData = new TempDataDictionary(); // Act mockController.Object.TempData["Key"] = "Value"; // Assert Assert.True(mockController.Object.TempData.ContainsKey("Key")); } [Fact] public void TryUpdateModelCallsModelBinderForModel() { // Arrange MyModel myModel = new MyModelSubclassed(); IValueProvider valueProvider = new SimpleValueProvider(); Controller controller = new EmptyController(); controller.ControllerContext = GetControllerContext("someAction"); // Act bool returned = controller.TryUpdateModel(myModel, "somePrefix", new[] { "prop1", "prop2" }, null, valueProvider); // Assert Assert.True(returned); Assert.Equal(valueProvider, myModel.BindingContext.ValueProvider); Assert.Equal("somePrefix", myModel.BindingContext.ModelName); Assert.Equal(controller.ModelState, myModel.BindingContext.ModelState); Assert.Equal(typeof(MyModel), myModel.BindingContext.ModelType); Assert.True(myModel.BindingContext.PropertyFilter("prop1")); Assert.True(myModel.BindingContext.PropertyFilter("prop2")); Assert.False(myModel.BindingContext.PropertyFilter("prop3")); } [Fact] public void TryUpdateModelReturnsFalseIfModelStateInvalid() { // Arrange MyModel myModel = new MyModelSubclassed(); Controller controller = new EmptyController(); controller.ModelState.AddModelError("key", "some exception message"); // Act bool returned = controller.TryUpdateModel(myModel, new SimpleValueProvider()); // Assert Assert.False(returned); } [Fact] public void TryUpdateModelSuppliesControllerValueProviderIfNoValueProviderSpecified() { // Arrange MyModel myModel = new MyModelSubclassed(); IValueProvider valueProvider = new SimpleValueProvider(); Controller controller = new EmptyController(); controller.ValueProvider = valueProvider; // Act bool returned = controller.TryUpdateModel(myModel, "somePrefix", new[] { "prop1", "prop2" }); // Assert Assert.True(returned); Assert.Equal(valueProvider, myModel.BindingContext.ValueProvider); } [Fact] public void TryUpdateModelSuppliesEmptyModelNameIfNoPrefixSpecified() { // Arrange MyModel myModel = new MyModelSubclassed(); Controller controller = new EmptyController(); // Act bool returned = controller.TryUpdateModel(myModel, new[] { "prop1", "prop2" }, new SimpleValueProvider()); // Assert Assert.True(returned); Assert.Equal(String.Empty, myModel.BindingContext.ModelName); } [Fact] public void TryUpdateModelThrowsIfModelIsNull() { // Arrange Controller controller = new EmptyController(); // Act & Assert Assert.ThrowsArgumentNull( delegate { controller.TryUpdateModel(null, new SimpleValueProvider()); }, "model"); } [Fact] public void TryUpdateModelThrowsIfValueProviderIsNull() { // Arrange Controller controller = new EmptyController(); // Act & Assert Assert.ThrowsArgumentNull( delegate { controller.TryUpdateModel(new object(), null, null, null, null); }, "valueProvider"); } [Fact] public void UpdateModelReturnsIfModelStateValid() { // Arrange MyModel myModel = new MyModelSubclassed(); Controller controller = new EmptyController(); // Act controller.UpdateModel(myModel, new SimpleValueProvider()); // Assert // nothing to do - if we got here, the test passed } [Fact] public void TryUpdateModelWithoutBindPropertiesImpliesAllPropertiesAreUpdateable() { // Arrange MyModel myModel = new MyModelSubclassed(); Controller controller = new EmptyController(); // Act bool returned = controller.TryUpdateModel(myModel, "somePrefix", new SimpleValueProvider()); // Assert Assert.True(returned); Assert.True(myModel.BindingContext.PropertyFilter("prop1")); Assert.True(myModel.BindingContext.PropertyFilter("prop2")); Assert.True(myModel.BindingContext.PropertyFilter("prop3")); } [Fact] public void UpdateModelSuppliesControllerValueProviderIfNoValueProviderSpecified() { // Arrange MyModel myModel = new MyModelSubclassed(); IValueProvider valueProvider = new SimpleValueProvider(); Controller controller = new EmptyController() { ValueProvider = valueProvider }; // Act controller.UpdateModel(myModel, "somePrefix", new[] { "prop1", "prop2" }); // Assert Assert.Equal(valueProvider, myModel.BindingContext.ValueProvider); } [Fact] public void UpdateModelThrowsIfModelStateInvalid() { // Arrange MyModel myModel = new MyModelSubclassed(); Controller controller = new EmptyController(); controller.ModelState.AddModelError("key", "some exception message"); // Act & assert Assert.Throws( delegate { controller.UpdateModel(myModel, new SimpleValueProvider()); }, "The model of type 'System.Web.Mvc.Test.ControllerTest+MyModel' could not be updated."); } [Fact] public void UpdateModelWithoutBindPropertiesImpliesAllPropertiesAreUpdateable() { // Arrange MyModel myModel = new MyModelSubclassed(); Controller controller = new EmptyController(); // Act controller.UpdateModel(myModel, "somePrefix", new SimpleValueProvider()); // Assert Assert.True(myModel.BindingContext.PropertyFilter("prop1")); Assert.True(myModel.BindingContext.PropertyFilter("prop2")); Assert.True(myModel.BindingContext.PropertyFilter("prop3")); } [Fact] public void Json() { // Arrange MyModel model = new MyModel(); Controller controller = new EmptyController(); // Act JsonResult result = controller.Json(model); // Assert Assert.Same(model, result.Data); Assert.Null(result.ContentType); Assert.Null(result.ContentEncoding); Assert.Equal(JsonRequestBehavior.DenyGet, result.JsonRequestBehavior); } [Fact] public void JsonWithContentType() { // Arrange MyModel model = new MyModel(); Controller controller = new EmptyController(); // Act JsonResult result = controller.Json(model, "text/xml"); // Assert Assert.Same(model, result.Data); Assert.Equal("text/xml", result.ContentType); Assert.Null(result.ContentEncoding); Assert.Equal(JsonRequestBehavior.DenyGet, result.JsonRequestBehavior); } [Fact] public void JsonWithContentTypeAndEncoding() { // Arrange MyModel model = new MyModel(); Controller controller = new EmptyController(); // Act JsonResult result = controller.Json(model, "text/xml", Encoding.UTF32); // Assert Assert.Same(model, result.Data); Assert.Equal("text/xml", result.ContentType); Assert.Equal(Encoding.UTF32, result.ContentEncoding); Assert.Equal(JsonRequestBehavior.DenyGet, result.JsonRequestBehavior); } [Fact] public void JsonWithBehavior() { // Arrange MyModel model = new MyModel(); Controller controller = new EmptyController(); // Act JsonResult result = controller.Json(model, JsonRequestBehavior.AllowGet); // Assert Assert.Same(model, result.Data); Assert.Null(result.ContentType); Assert.Null(result.ContentEncoding); Assert.Equal(JsonRequestBehavior.AllowGet, result.JsonRequestBehavior); } [Fact] public void JsonWithContentTypeAndBehavior() { // Arrange MyModel model = new MyModel(); Controller controller = new EmptyController(); // Act JsonResult result = controller.Json(model, "text/xml", JsonRequestBehavior.AllowGet); // Assert Assert.Same(model, result.Data); Assert.Equal("text/xml", result.ContentType); Assert.Null(result.ContentEncoding); Assert.Equal(JsonRequestBehavior.AllowGet, result.JsonRequestBehavior); } [Fact] public void JsonWithContentTypeAndEncodingAndBehavior() { // Arrange MyModel model = new MyModel(); Controller controller = new EmptyController(); // Act JsonResult result = controller.Json(model, "text/xml", Encoding.UTF32, JsonRequestBehavior.AllowGet); // Assert Assert.Same(model, result.Data); Assert.Equal("text/xml", result.ContentType); Assert.Equal(Encoding.UTF32, result.ContentEncoding); Assert.Equal(JsonRequestBehavior.AllowGet, result.JsonRequestBehavior); } [Fact] public void ExecuteDoesNotCallTempDataLoadOrSave() { // Arrange TempDataDictionary tempData = new TempDataDictionary(); ViewContext viewContext = new ViewContext { TempData = tempData }; RouteData routeData = new RouteData(); routeData.DataTokens[ControllerContext.ParentActionViewContextToken] = viewContext; routeData.Values["action"] = "SimpleAction"; RequestContext requestContext = new RequestContext(HttpContextHelpers.GetMockHttpContext().Object, routeData); // Strict == no default implementations == calls to Load & Save are not allowed Mock tempDataProvider = new Mock(MockBehavior.Strict); SimpleController controller = new SimpleController(); controller.ValidateRequest = false; // Act ((IController)controller).Execute(requestContext); // Assert tempDataProvider.Verify(); } // Model validation [Fact] public void TryValidateModelGuardClauses() { // Arrange Controller controller = new SimpleController(); // Act & Assert Assert.ThrowsArgumentNull( () => controller.TryValidateModel(null), "model"); } [Fact] public void TryValidateModelWithValidModel() { // Arrange Controller controller = new SimpleController(); TryValidateModelModel model = new TryValidateModelModel { IntegerProperty = 15 }; // Act bool result = controller.TryValidateModel(model); // Assert Assert.True(result); Assert.True(controller.ModelState.IsValid); } [Fact] public void TryValidateModelWithInvalidModel() { // Arrange Controller controller = new SimpleController(); TryValidateModelModel model = new TryValidateModelModel { IntegerProperty = 5 }; // Act bool result = controller.TryValidateModel(model, "Prefix"); // Assert Assert.False(result); Assert.Equal("Out of range!", controller.ModelState["Prefix.IntegerProperty"].Errors[0].ErrorMessage); } [Fact] public void ValidateModelGuardClauses() { // Arrange Controller controller = new SimpleController(); // Act & Assert Assert.ThrowsArgumentNull( () => controller.ValidateModel(null), "model"); } [Fact] public void ValidateModelWithValidModel() { // Arrange Controller controller = new SimpleController(); TryValidateModelModel model = new TryValidateModelModel { IntegerProperty = 15 }; // Act controller.ValidateModel(model); // Assert Assert.True(controller.ModelState.IsValid); } [Fact] public void ValidateModelWithInvalidModel() { // Arrange Controller controller = new SimpleController(); TryValidateModelModel model = new TryValidateModelModel { IntegerProperty = 5 }; // Act & Assert Assert.Throws( () => controller.ValidateModel(model, "Prefix"), "The model of type '" + model.GetType().FullName + "' is not valid."); Assert.Equal("Out of range!", controller.ModelState["Prefix.IntegerProperty"].Errors[0].ErrorMessage); } [Fact] public void ValidateControllerUsesCachedResolver() { var controller = new EmptyController(); var resolver = controller.Resolver; Assert.Equal(DependencyResolver.CurrentCache.GetType(), resolver.GetType()); } [Fact] public void CreateActionInvokerCallsIntoResolverInstance() { // Controller uses an IDependencyResolver to create an IActionInvoker. var controller = new EmptyController(); Mock resolverMock = new Mock(); Mock actionInvokerMock = new Mock(); resolverMock.Setup(r => r.GetService(typeof(IAsyncActionInvoker))).Returns(actionInvokerMock.Object); controller.Resolver = resolverMock.Object; var ai = controller.CreateActionInvoker(); resolverMock.Verify(r => r.GetService(typeof(IAsyncActionInvoker)), Times.Once()); Assert.Same(actionInvokerMock.Object, ai); } [Fact] public void CreateActionInvokerCallsIntoResolverInstanceAndCreatesANewOneIfNecessary() { // If IDependencyResolver is set, but empty, falls back and still creates. var controller = new EmptyController(); Mock resolverMock = new Mock(); resolverMock.Setup(r => r.GetService(typeof(IAsyncActionInvoker))).Returns(null); controller.Resolver = resolverMock.Object; IActionInvoker ai = controller.CreateActionInvoker(); resolverMock.Verify(r => r.GetService(typeof(IAsyncActionInvoker)), Times.Once()); Assert.NotNull(ai); } [Fact] public void CreateTempProviderWithResolver() { // Controller uses an IDependencyResolver to create an IActionInvoker. var controller = new EmptyController(); Mock resolverMock = new Mock(); Mock tempMock = new Mock(); resolverMock.Setup(r => r.GetService(typeof(ITempDataProvider))).Returns(tempMock.Object); controller.Resolver = resolverMock.Object; ITempDataProvider temp = controller.CreateTempDataProvider(); resolverMock.Verify(r => r.GetService(typeof(ITempDataProvider)), Times.Once()); Assert.Same(tempMock.Object, temp); } private class TryValidateModelModel { [Range(10, 20, ErrorMessage = "Out of range!")] public int IntegerProperty { get; set; } } // Helpers private class SimpleController : Controller { public SimpleController() { ControllerContext = new ControllerContext { Controller = this }; } public void SimpleAction() { } } private static ControllerContext GetControllerContext(string actionName) { RouteData rd = new RouteData(); rd.Values["action"] = actionName; Mock mockHttpContext = HttpContextHelpers.GetMockHttpContext(); mockHttpContext.Setup(c => c.Session).Returns((HttpSessionStateBase)null); return new ControllerContext(mockHttpContext.Object, rd, new Mock().Object); } private static ControllerContext GetControllerContext(string actionName, string controllerName) { RouteData rd = new RouteData(); rd.Values["action"] = actionName; rd.Values["controller"] = controllerName; Mock mockHttpContext = new Mock(); mockHttpContext.Setup(c => c.Session).Returns((HttpSessionStateBase)null); return new ControllerContext(mockHttpContext.Object, rd, new Mock().Object); } private static Controller GetEmptyController() { ControllerContext context = GetControllerContext("Foo"); var controller = new EmptyController() { ControllerContext = context, RouteCollection = new RouteCollection(), TempData = new TempDataDictionary(), TempDataProvider = new SessionStateTempDataProvider() }; return controller; } private static HttpSessionStateBase GetEmptySession() { HttpSessionStateMock mockSession = new HttpSessionStateMock(); return mockSession; } private sealed class HttpSessionStateMock : HttpSessionStateBase { private Hashtable _sessionData = new Hashtable(StringComparer.OrdinalIgnoreCase); public override void Remove(string name) { Assert.Equal(SessionStateTempDataProvider.TempDataSessionStateKey, name); _sessionData.Remove(name); } public override object this[string name] { get { Assert.Equal(SessionStateTempDataProvider.TempDataSessionStateKey, name); return _sessionData[name]; } set { Assert.Equal(SessionStateTempDataProvider.TempDataSessionStateKey, name); _sessionData[name] = value; } } } public class Person { public string Name { get; set; } public int Age { get; set; } } private class EmptyController : Controller { public new void HandleUnknownAction(string actionName) { base.HandleUnknownAction(actionName); } public void PublicInitialize(RequestContext requestContext) { base.Initialize(requestContext); } // Test can expose protected method as public. public new IActionInvoker CreateActionInvoker() { return base.CreateActionInvoker(); } public new ITempDataProvider CreateTempDataProvider() { return base.CreateTempDataProvider(); } } private sealed class UnknownActionController : Controller { public bool WasCalled; protected override void HandleUnknownAction(string actionName) { WasCalled = true; } } private sealed class TempDataHomeController : Controller { public ActionResult Index() { // Save UserID into TempData and redirect to greeting page TempData["UserID"] = "user123"; return RedirectToAction("GreetUser"); } public ActionResult GreetUser() { // Check that the UserID is present. If it's not // there, redirect to error page. If it is, show // the greet user view. if (!TempData.ContainsKey("UserID")) { return RedirectToAction("ErrorPage"); } ViewData["NewUserID"] = TempData["UserID"]; return View("GreetUser"); } } public class BrokenController : Controller { public BrokenController() { ActionInvoker = new ControllerActionInvoker() { DescriptorCache = new ControllerDescriptorCache() }; } public ActionResult Crash() { TempData["Key1"] = "Value1"; throw new InvalidOperationException("Crashing...."); } } private sealed class TestRouteController : Controller { public ActionResult Index() { return RedirectToAction("SomeAction"); } } [ModelBinder(typeof(MyModelBinder))] private class MyModel { public ControllerContext ControllerContext; public ModelBindingContext BindingContext; } private class MyModelSubclassed : MyModel { } private class MyModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { MyModel myModel = (MyModel)bindingContext.Model; myModel.ControllerContext = controllerContext; myModel.BindingContext = bindingContext; return myModel; } } } internal class EmptyTempDataProvider : ITempDataProvider { public void SaveTempData(ControllerContext controllerContext, IDictionary values) { } public IDictionary LoadTempData(ControllerContext controllerContext) { return new Dictionary(StringComparer.OrdinalIgnoreCase); } } }