First, something to mock. Here's an interface with some methods we can use.
namespace Standups.Models.Example { public class ExampleAccount { public int AccountNumber { get; set; } public bool IsOpen { get; set; } = false; } // An example repository for mocking example public interface IAccountRepository { // Simple property string Name { get; set; } // Parameterless method bool IsValid(); // Primitive type parameter int GetBaseAccountNumber(int num); // Object type parameter bool Update(ExampleAccount ea); // Object type returned ExampleAccount GetNewAccount(); } }
And here are some Moq examples for how you can mock different kinds of methods. Yes, we're not actually mocking any useful behavior here -- this is just to show syntax and general organization.
using System; using Moq; using NUnit.Framework; using Standups.Models.Example; namespace Tests.Examples { [TestFixture] public class ExampleTests { [Test] public void Test_A_Property() { // Arrange string expected = "George"; Mock<IAccountRepository> mock = new Mock<IAccountRepository>(); mock.Setup(m => m.Name) .Returns(expected); // Act IAccountRepository ar = mock.Object; string name = ar.Name; // in reality, do something useful with this IAccountRepository instance // Assert Assert.That(name, Is.EqualTo(expected)); } [Test] public void Test_Parameterless_Method() { Mock<IAccountRepository> mock = new Mock<IAccountRepository>(); mock.Setup(m => m.IsValid()) .Returns(true); IAccountRepository ar = mock.Object; Assert.That(ar.IsValid(), Is.True); } [Test] public void Test_SimpleParameter_Method() { Mock<IAccountRepository> mock = new Mock<IAccountRepository>(); mock.Setup(m => m.GetBaseAccountNumber(5)) .Returns(100); IAccountRepository ar = mock.Object; Assert.That(ar.GetBaseAccountNumber(5), Is.EqualTo(100)); } [Test] public void Test_SimpleParameter_Method_WithAny() { Mock<IAccountRepository> mock = new Mock<IAccountRepository>(); mock.Setup(m => m.GetBaseAccountNumber(It.IsAny<int>())) .Returns(100); IAccountRepository ar = mock.Object; Assert.That(ar.GetBaseAccountNumber(88), Is.EqualTo(100)); } [Test] public void Test_Method_Taking_An_Object() { ExampleAccount ea = new ExampleAccount() { AccountNumber = 12345 }; Mock<IAccountRepository> mock = new Mock<IAccountRepository>(); mock.Setup(m => m.Update(It.IsAny<ExampleAccount>())) .Returns(true); IAccountRepository ar = mock.Object; Assert.That(ar.Update(ea), Is.True); } [Test] public void Test_Method_Returning_An_Object() { Mock<IAccountRepository> mock = new Mock<IAccountRepository>(); mock.Setup(m => m.GetNewAccount()) .Returns( new ExampleAccount { AccountNumber = 42, IsOpen = true} ); IAccountRepository ar = mock.Object; Assert.That(ar.GetNewAccount().IsOpen, Is.True); } } }
Here's a starting example for mocking part of a repository. Note: there are plenty of examples out there you can find that show mocking the usual CRUD functionality.
namespace Standups.Models.Abstract { public interface ISUPRepository : IDisposable { IEnumerable<SUPUser> SUPUsers { get; } } }
namespace Standups.Models.Concrete { public class EFSUPRepository : ISUPRepository { private SUPContext db = new SUPContext(); public IEnumerable<SUPUser> SUPUsers { get { return db.SUPUsers; } } public void Dispose() { db.Dispose(); } } }
And a couple tests using it.
namespace Tests.TestControllers { [TestFixture] public class TestHome { private Mock<ISUPRepository> mock; [SetUp] public void SetupUserMock() { SUPGroup[] groups = new SUPGroup[] { new SUPGroup { ID = 1, Name = "Group 1" }, new SUPGroup { ID = 2, Name = "Group 2" } }; mock = new Mock<ISUPRepository>(); mock.Setup(m => m.SUPUsers) .Returns( new SUPUser[] { new SUPUser {ID = 1, FirstName = "Bob", LastName = "Roberts", SUPGroupID = 1, SUPGroup = groups[0], ASPNetIdentityID = "id001"}, new SUPUser {ID = 2, FirstName = "Julie", LastName = "Juliet", SUPGroupID = 1, SUPGroup = groups[0], ASPNetIdentityID = "id002"}, new SUPUser {ID = 3, FirstName = "Rick", LastName = "Rickard", SUPGroupID = null, SUPGroup = null, ASPNetIdentityID = "id003"}, new SUPUser {ID = 4, FirstName = "Sue", LastName = "Suarez", SUPGroupID = 2, SUPGroup = groups[1], ASPNetIdentityID = "id004"}, new SUPUser {ID = 5, FirstName = "John", LastName = "Johanson", SUPGroupID = null, SUPGroup = null, ASPNetIdentityID = "id005"} }); } [Test] public void UserNeedsGroup() { // Arrange HomeController controller = new HomeController(mock.Object); // Act SUPUser u = mock.Object.SUPUsers.ElementAt(2); // Assert Assert.That(controller.SUPUserNeedsGroupSet(u), Is.True); } [Test] public void UserDoesNotNeedGroup() { // Arrange HomeController controller = new HomeController(mock.Object); // Act SUPUser u = mock.Object.SUPUsers.ElementAt(0); // Assert Assert.That(controller.SUPUserNeedsGroupSet(u), Is.False); } // This method mocks enough of Identity to be able to test the // view produced by this controller action method public ControllerContext GetMockControllerContext(SUPUser u) { // mock parts of Identity: // Using parts of http://stackoverflow.com/questions/22762338/how-do-i-mock-user-identity-getuserid and // http://stackoverflow.com/questions/758066/how-to-mock-controller-user-using-moq // mock an Identity with a known id var identity = new GenericIdentity("TestUsername"); identity.AddClaim(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", u.ASPNetIdentityID)); // This line above is fragile in that is assumes ASP.NET Identity looks for exactly this string for the claim key string. // It will fail if not an exact match. If it fails then the lookup fails and GetUserId() returns null, meaning no User // is found. Look at the source code for: IdentityExtensions.GetUserId() // mock an IPrincipal that uses the mock identity Mock<IPrincipal> mockIPrincipal = new Mock<IPrincipal>(); mockIPrincipal.Setup(p => p.Identity) .Returns(identity); // mock a controller context for the controller to use Mock<ControllerContext> mockControllerContext = new Mock<ControllerContext>(); mockControllerContext.Setup(p => p.HttpContext.User) .Returns(mockIPrincipal.Object); return mockControllerContext.Object; } [Test] public void AuthenticatedUserWhoNeedsGroup_ShouldSetViewData() { HomeController controller = new HomeController(mock.Object); // user for this test, who needs to have a group set SUPUser u = mock.Object.SUPUsers.ElementAt(2); // Use the context, which will return the given identity id controller.ControllerContext = GetMockControllerContext(u); // Generate enough of the view to hold the ViewBag data we set there ViewResult index = (ViewResult) controller.Index(); // See if it got set Assert.That(index.ViewData["NeedsGroup"], Is.True); } // NOTE: need to refactor this duplicated code into a common method [Test] public void AuthenticatedUserWhoNeedsNOGroup_ShouldNOTSetViewData() { HomeController controller = new HomeController(mock.Object); // user for this test who already has a group set SUPUser u = mock.Object.SUPUsers.ElementAt(1); // Use the context, which will return the given identity id controller.ControllerContext = GetMockControllerContext(u); // Generate enough of the view to hold the ViewBag data we set there ViewResult index = (ViewResult)controller.Index(); // See if it got set Assert.That(index.ViewData["NeedsGroup"], Is.False); } } }