Click here to Skip to main content
15,885,278 members
Articles / Web Development / ASP.NET

Using Munq IOC Container Version 3 in ASP.NET MVC 3

Rate me:
Please Sign up or sign in to vote.
4.93/5 (15 votes)
24 Sep 2019CPOL5 min read 57.5K   676   23  
Munq IOC Container Version 3 has been released on CodePlex and as a NuGet package. This article demonstrates how to integrate the IOC Container into an ASP.NET MVC3 project.
using System;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MunqMvc3Sample;
using MunqMvc3Sample.Controllers;
using MunqMvc3Sample.Models;

namespace MunqMvc3Sample.Tests.Controllers
{

	[TestClass]
	public class AccountControllerTest
	{

		[TestMethod]
		public void ChangePassword_Get_ReturnsView()
		{
			// Arrange
			AccountController controller = GetAccountController();

			// Act
			ActionResult result = controller.ChangePassword();

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			Assert.AreEqual(10, ((ViewResult)result).ViewData["PasswordLength"]);
		}

		[TestMethod]
		public void ChangePassword_Post_ReturnsRedirectOnSuccess()
		{
			// Arrange
			AccountController controller = GetAccountController();
			ChangePasswordModel model = new ChangePasswordModel()
			{
				OldPassword = "goodOldPassword",
				NewPassword = "goodNewPassword",
				ConfirmPassword = "goodNewPassword"
			};

			// Act
			ActionResult result = controller.ChangePassword(model);

			// Assert
			Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
			RedirectToRouteResult redirectResult = (RedirectToRouteResult)result;
			Assert.AreEqual("ChangePasswordSuccess", redirectResult.RouteValues["action"]);
		}

		[TestMethod]
		public void ChangePassword_Post_ReturnsViewIfChangePasswordFails()
		{
			// Arrange
			AccountController controller = GetAccountController();
			ChangePasswordModel model = new ChangePasswordModel()
			{
				OldPassword = "goodOldPassword",
				NewPassword = "badNewPassword",
				ConfirmPassword = "badNewPassword"
			};

			// Act
			ActionResult result = controller.ChangePassword(model);

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			ViewResult viewResult = (ViewResult)result;
			Assert.AreEqual(model, viewResult.ViewData.Model);
			Assert.AreEqual("The current password is incorrect or the new password is invalid.", controller.ModelState[""].Errors[0].ErrorMessage);
			Assert.AreEqual(10, viewResult.ViewData["PasswordLength"]);
		}

		[TestMethod]
		public void ChangePassword_Post_ReturnsViewIfModelStateIsInvalid()
		{
			// Arrange
			AccountController controller = GetAccountController();
			ChangePasswordModel model = new ChangePasswordModel()
			{
				OldPassword = "goodOldPassword",
				NewPassword = "goodNewPassword",
				ConfirmPassword = "goodNewPassword"
			};
			controller.ModelState.AddModelError("", "Dummy error message.");

			// Act
			ActionResult result = controller.ChangePassword(model);

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			ViewResult viewResult = (ViewResult)result;
			Assert.AreEqual(model, viewResult.ViewData.Model);
			Assert.AreEqual(10, viewResult.ViewData["PasswordLength"]);
		}

		[TestMethod]
		public void ChangePasswordSuccess_ReturnsView()
		{
			// Arrange
			AccountController controller = GetAccountController();

			// Act
			ActionResult result = controller.ChangePasswordSuccess();

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
		}

		[TestMethod]
		public void LogOff_LogsOutAndRedirects()
		{
			// Arrange
			var mockFormsAuthenticationService = new MockFormsAuthenticationService();
			var mockMembershipService = new MockMembershipService();
			AccountController controller = GetAccountController(mockFormsAuthenticationService, 
																	mockMembershipService);

			// Act
			ActionResult result = controller.LogOff();

			// Assert
			Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
			RedirectToRouteResult redirectResult = (RedirectToRouteResult)result;
			Assert.AreEqual("Home", redirectResult.RouteValues["controller"]);
			Assert.AreEqual("Index", redirectResult.RouteValues["action"]);
			Assert.IsTrue(mockFormsAuthenticationService.SignOut_WasCalled);
		}

		[TestMethod]
		public void LogOn_Get_ReturnsView()
		{
			// Arrange
			AccountController controller = GetAccountController();

			// Act
			ActionResult result = controller.LogOn();

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
		}

		[TestMethod]
		public void LogOn_Post_ReturnsRedirectOnSuccess_WithoutReturnUrl()
		{
			// Arrange
			var mockFormsAuthenticationService = new MockFormsAuthenticationService();
			var mockMembershipService = new MockMembershipService();
			AccountController controller = GetAccountController(mockFormsAuthenticationService, 
																	mockMembershipService);

			LogOnModel model = new LogOnModel()
			{
				UserName = "someUser",
				Password = "goodPassword",
				RememberMe = false
			};

			// Act
			ActionResult result = controller.LogOn(model, null);

			// Assert
			Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
			RedirectToRouteResult redirectResult = (RedirectToRouteResult)result;
			Assert.AreEqual("Home", redirectResult.RouteValues["controller"]);
			Assert.AreEqual("Index", redirectResult.RouteValues["action"]);
			Assert.IsTrue(mockFormsAuthenticationService.SignIn_WasCalled);
		}

		[TestMethod]
		public void LogOn_Post_ReturnsRedirectOnSuccess_WithLocalReturnUrl()
		{
			// Arrange
			var mockFormsAuthenticationService = new MockFormsAuthenticationService();
			var mockMembershipService = new MockMembershipService();
			AccountController controller = GetAccountController(mockFormsAuthenticationService,
																	mockMembershipService);
			LogOnModel model = new LogOnModel()
			{
				UserName = "someUser",
				Password = "goodPassword",
				RememberMe = false
			};

			// Act
			ActionResult result = controller.LogOn(model, "/someUrl");

			// Assert
			Assert.IsInstanceOfType(result, typeof(RedirectResult));
			RedirectResult redirectResult = (RedirectResult)result;
			Assert.AreEqual("/someUrl", redirectResult.Url);
			Assert.IsTrue(mockFormsAuthenticationService.SignIn_WasCalled);
		}

		[TestMethod]
		public void LogOn_Post_ReturnsRedirectToHomeOnSuccess_WithExternalReturnUrl()
		{
			// Arrange
			var mockFormsAuthenticationService = new MockFormsAuthenticationService();
			var mockMembershipService = new MockMembershipService();
			AccountController controller = GetAccountController(mockFormsAuthenticationService,
																	mockMembershipService);
			LogOnModel model = new LogOnModel()
			{
				UserName = "someUser",
				Password = "goodPassword",
				RememberMe = false
			};

			// Act
			ActionResult result = controller.LogOn(model, "http://malicious.example.net");

			// Assert
			Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
			RedirectToRouteResult redirectResult = (RedirectToRouteResult)result;
			Assert.AreEqual("Home", redirectResult.RouteValues["controller"]);
			Assert.AreEqual("Index", redirectResult.RouteValues["action"]);
			Assert.IsTrue(mockFormsAuthenticationService.SignIn_WasCalled);
		}

		[TestMethod]
		public void LogOn_Post_ReturnsViewIfModelStateIsInvalid()
		{
			// Arrange
			AccountController controller = GetAccountController();
			LogOnModel model = new LogOnModel()
			{
				UserName = "someUser",
				Password = "goodPassword",
				RememberMe = false
			};
			controller.ModelState.AddModelError("", "Dummy error message.");

			// Act
			ActionResult result = controller.LogOn(model, null);

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			ViewResult viewResult = (ViewResult)result;
			Assert.AreEqual(model, viewResult.ViewData.Model);
		}

		[TestMethod]
		public void LogOn_Post_ReturnsViewIfValidateUserFails()
		{
			// Arrange
			AccountController controller = GetAccountController();
			LogOnModel model = new LogOnModel()
			{
				UserName = "someUser",
				Password = "badPassword",
				RememberMe = false
			};

			// Act
			ActionResult result = controller.LogOn(model, null);

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			ViewResult viewResult = (ViewResult)result;
			Assert.AreEqual(model, viewResult.ViewData.Model);
			Assert.AreEqual("The user name or password provided is incorrect.", controller.ModelState[""].Errors[0].ErrorMessage);
		}

		[TestMethod]
		public void Register_Get_ReturnsView()
		{
			// Arrange
			AccountController controller = GetAccountController();

			// Act
			ActionResult result = controller.Register();

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			Assert.AreEqual(10, ((ViewResult)result).ViewData["PasswordLength"]);
		}

		[TestMethod]
		public void Register_Post_ReturnsRedirectOnSuccess()
		{
			// Arrange
			AccountController controller = GetAccountController();
			RegisterModel model = new RegisterModel()
			{
				UserName = "someUser",
				Email = "goodEmail",
				Password = "goodPassword",
				ConfirmPassword = "goodPassword"
			};

			// Act
			ActionResult result = controller.Register(model);

			// Assert
			Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult));
			RedirectToRouteResult redirectResult = (RedirectToRouteResult)result;
			Assert.AreEqual("Home", redirectResult.RouteValues["controller"]);
			Assert.AreEqual("Index", redirectResult.RouteValues["action"]);
		}

		[TestMethod]
		public void Register_Post_ReturnsViewIfRegistrationFails()
		{
			// Arrange
			AccountController controller = GetAccountController();
			RegisterModel model = new RegisterModel()
			{
				UserName = "duplicateUser",
				Email = "goodEmail",
				Password = "goodPassword",
				ConfirmPassword = "goodPassword"
			};

			// Act
			ActionResult result = controller.Register(model);

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			ViewResult viewResult = (ViewResult)result;
			Assert.AreEqual(model, viewResult.ViewData.Model);
			Assert.AreEqual("Username already exists. Please enter a different user name.", controller.ModelState[""].Errors[0].ErrorMessage);
			Assert.AreEqual(10, viewResult.ViewData["PasswordLength"]);
		}

		[TestMethod]
		public void Register_Post_ReturnsViewIfModelStateIsInvalid()
		{
			// Arrange
			AccountController controller = GetAccountController();
			RegisterModel model = new RegisterModel()
			{
				UserName = "someUser",
				Email = "goodEmail",
				Password = "goodPassword",
				ConfirmPassword = "goodPassword"
			};
			controller.ModelState.AddModelError("", "Dummy error message.");

			// Act
			ActionResult result = controller.Register(model);

			// Assert
			Assert.IsInstanceOfType(result, typeof(ViewResult));
			ViewResult viewResult = (ViewResult)result;
			Assert.AreEqual(model, viewResult.ViewData.Model);
			Assert.AreEqual(10, viewResult.ViewData["PasswordLength"]);
		}

		private static AccountController GetAccountController()
		{
			var mockFormsAuthenticationService = new MockFormsAuthenticationService();
			var mockMembershipService = new MockMembershipService();
			return GetAccountController(mockFormsAuthenticationService, mockMembershipService);
		}

		private static AccountController GetAccountController(MockFormsAuthenticationService mockFormsAuthenticationService, MockMembershipService mockMembershipService)
		{
			RequestContext requestContext = new RequestContext(new MockHttpContext(), new RouteData());
			AccountController controller = new AccountController(mockFormsAuthenticationService,
																	mockMembershipService)
			{
				Url = new UrlHelper(requestContext),
			};
			controller.ControllerContext = new ControllerContext()
			{
				Controller = controller,
				RequestContext = requestContext
			};
			return controller;
		}

		private class MockFormsAuthenticationService : IFormsAuthenticationService
		{
			public bool SignIn_WasCalled;
			public bool SignOut_WasCalled;

			public void SignIn(string userName, bool createPersistentCookie)
			{
				// verify that the arguments are what we expected
				Assert.AreEqual("someUser", userName);
				Assert.IsFalse(createPersistentCookie);

				SignIn_WasCalled = true;
			}

			public void SignOut()
			{
				SignOut_WasCalled = true;
			}
		}

		private class MockHttpContext : HttpContextBase
		{
			private readonly IPrincipal _user = new GenericPrincipal(new GenericIdentity("someUser"), null /* roles */);
			private readonly HttpRequestBase _request = new MockHttpRequest();

			public override IPrincipal User
			{
				get
				{
					return _user;
				}
				set
				{
					base.User = value;
				}
			}

			public override HttpRequestBase Request
			{
				get
				{
					return _request;
				}
			}
		}

		private class MockHttpRequest : HttpRequestBase
		{
			private readonly Uri _url = new Uri("http://mysite.example.com/");

			public override Uri Url
			{
				get
				{
					return _url;
				}
			}
		}

		private class MockMembershipService : IMembershipService
		{
			public int MinPasswordLength
			{
				get { return 10; }
			}

			public bool ValidateUser(string userName, string password)
			{
				return (userName == "someUser" && password == "goodPassword");
			}

			public MembershipCreateStatus CreateUser(string userName, string password, string email)
			{
				if (userName == "duplicateUser")
				{
					return MembershipCreateStatus.DuplicateUserName;
				}

				// verify that values are what we expected
				Assert.AreEqual("goodPassword", password);
				Assert.AreEqual("goodEmail", email);

				return MembershipCreateStatus.Success;
			}

			public bool ChangePassword(string userName, string oldPassword, string newPassword)
			{
				return (userName == "someUser" && oldPassword == "goodOldPassword" && newPassword == "goodNewPassword");
			}
		}

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) CodeProject
Canada Canada
As Senior Architect, Matthew is responsible for the Architecture, Design, and Coding of the CodeProject software as well as Manager of the Infrastructure that runs the web site.

Matthew works on improving the performance and experience of the Code Project site for users, clients, and administrators.

Matthew has more years of software development, QA and architecture experience under his belt than he likes to admit. He graduated from the University of Waterloo with a B.Sc. in Electrical Engineering. He started out developing micro-processor based hardware and software including compilers and operating systems.
His current focus is on .NET web development including jQuery, Webforms, MVC, AJAX, and patterns and practices for creating better websites.
He is the author of the Munq IOC, the fastest ASP.NET focused IOC Container.
His non-programming passions include golf, pool, curling, reading and building stuff for the house.

Comments and Discussions