Implementing Unit Test using MS Test

1.     Implementing Test at the business

In order to start writing unit test there are a couple of things you have to know ,

First as we have discussed earlier all the layers are separated nicely so you need something which simulates the DI task , on which we can configure all dependency required to run our test. For this purpose I will use Moq(Read more: https://code.google.com/p/moq/)

1. Install Moq in your test project

   https://code.google.com/p/moq/downloads/detail?name=Moq.4.0.10827.Final.zip&can=2&q=

   Extract and reference in your test project

2.Write your test class as shown below

Testing the Services
//ProductServiceTests.cs


[TestClass]
    public class ProductServiceTest
    {
        [TestMethod]
        public void Can_Add_Product_Service()
        {
            //Arrange
            List<Product> products = new List<Product>()
                                         {
                                             new Product(){Description="P1",ProductId=1,ProductName="p1Name"},
                                             new Product(){Description="P2",ProductId=2,ProductName="p2Name"},
                                             new Product(){Description="P3",ProductId=3,ProductName="p3Name"},
                                             new Product(){Description="P4",ProductId=4,ProductName="p4Name"},
                                             new Product(){Description="P5",ProductId=5,ProductName="p5Name"},
                                             new Product(){Description="P6",ProductId=6,ProductName="p6Name"}
                                         };
            Mock<IGenericRepository<Product>> mock1 = new Mock<IGenericRepository<Product>>();


            //Here we are going to mock repository GetAll method
            mock1.Setup(m => m.GetAll()).Returns(products);
         
            //Here we are going to mock repository Add method
            mock1.Setup(m => m.Add(It.IsAny<Product>())).Returns((Product target) =>
            {
                var original = products.FirstOrDefault(
                    q => q.ProductId == target.ProductId);


                if (original != null)
                {
                    return false;
                }

                products.Add(target);
                return true;
            });
         
            //Now we have our repository ready for property injection


            //Here we are going to mock our IUnitOfWork
            Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();
           
            //Here we are going to inject our repository to the property
            //mock.SetupProperty(m => m.ProductRepository).SetReturnsDefault(mock1.Object);
           mock.Setup(m => m.ProductRepository).Returns(mock1.Object);

            //Now our UnitOfWork is ready to be injected to the service
            //Here we inject UnitOfWork to constractor of our service
            ProductService productService = new ProductService(mock.Object);

            //Act
            productService.AddProduct(new Product
                                          {
                                              ProductId = 7,
                                              ProductName = "P7Name",
                                              Description = "P7"
                                          });
            var result = productService.GetAllProduct();
            var newProduct = result.FirstOrDefault(t => t.ProductId == 7);

            //Assert
            Assert.AreEqual(products.Count, result.Count);
            Assert.AreEqual("P7Name", newProduct.ProductName);
            Assert.AreEqual("P7", newProduct.Description);
        }


        [TestMethod]
        public void Can_Get_All_Product_Service()
        {
            //Arrange
            List<Product> products = new List<Product>()
                                         {
                                             new Product(){Description="P1",ProductId=1,ProductName="p1Name"},
                                             new Product(){Description="P2",ProductId=2,ProductName="p2Name"},
                                             new Product(){Description="P3",ProductId=3,ProductName="p3Name"},
                                             new Product(){Description="P4",ProductId=4,ProductName="p4Name"},
                                             new Product(){Description="P5",ProductId=5,ProductName="p5Name"},
                                             new Product(){Description="P6",ProductId=6,ProductName="p6Name"}
                                         };
            Mock<IGenericRepository<Product>> mock1 = new Mock<IGenericRepository<Product>>();


            //Here we are going to mock repository GetAll method
            mock1.Setup(m => m.GetAll()).Returns(products);

            //Now we have our repository ready for property injection


            //Here we are going to mock our IUnitOfWork
            Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();


            //Here we are going to inject our repository to the property
            mock.Setup(m => m.ProductRepository).Returns(mock1.Object);

            //Now our UnitOfWork is ready to be injected to the service
            //Here we inject UnitOfWork to constractor of our service
            ProductService productService = new ProductService(mock.Object);

            //Act
            var result = productService.GetAllProduct();
            //Assert
            Assert.AreEqual(products,result);

        }


        [TestMethod]
        public void Can_Update_Product_Service()
        {
            //Arrange
            List<Product> products = new List<Product>()
                                         {
                                             new Product(){Description="P1",ProductId=1,ProductName="p1Name"},
                                             new Product(){Description="P2",ProductId=2,ProductName="p2Name"},
                                             new Product(){Description="P3",ProductId=3,ProductName="p3Name"},
                                             new Product(){Description="P4",ProductId=4,ProductName="p4Name"},
                                             new Product(){Description="P5",ProductId=5,ProductName="p5Name"},
                                             new Product(){Description="P6",ProductId=6,ProductName="p6Name"}
                                         };
            Mock<IGenericRepository<Product>> mock1 = new Mock<IGenericRepository<Product>>();


          
            //Here we are going to mock repository Edit method
            mock1.Setup(m => m.Edit(It.IsAny<Product>())).Returns((Product target) =>
            {
                var original = products.FirstOrDefault( q => q.ProductId == target.ProductId);


                if (original == null)
                {
                    return false;
                }

                original.ProductName = target.ProductName;

                original.Description = target.Description;

                return true;
            });
          
            //Now we have our repository ready for property injection

            //Here we are going to mock our IUnitOfWork
            Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();

            //Here we are going to inject our repository to the property
            mock.Setup(m => m.ProductRepository).Returns(mock1.Object);

            //Now our UnitOfWork is ready to be injected to the service
            //Here we inject UnitOfWork to constractor of our service
            ProductService productService = new ProductService(mock.Object);

            //Act

            var updatedProduct = new Product() {ProductId = 1, ProductName = "p1NameModified", Description = "p1Modified"};
            productService.UpdateProduct(updatedProduct);
            var actualProduct = products.FirstOrDefault(t => t.ProductId == 1);
            //Assert
           
            Assert.AreEqual(actualProduct.ProductName ,updatedProduct.ProductName);
            Assert.AreEqual(actualProduct.Description, updatedProduct.Description);


        }
        [TestMethod]
        public void Can_Delete_Product_Service()
        {
            //Arrange
            List<Product> products = new List<Product>()
                                         {
                                             new Product(){Description="P1",ProductId=1,ProductName="p1Name"},
                                             new Product(){Description="P2",ProductId=2,ProductName="p2Name"},
                                             new Product(){Description="P3",ProductId=3,ProductName="p3Name"},
                                             new Product(){Description="P4",ProductId=4,ProductName="p4Name"},
                                             new Product(){Description="P5",ProductId=5,ProductName="p5Name"},
                                             new Product(){Description="P6",ProductId=6,ProductName="p6Name"},
                                         };
            Mock<IGenericRepository<Product>> mock1 = new Mock<IGenericRepository<Product>>();


            //Here we are going to mock repository FindById Method
            mock1.Setup(m => m.FindById(It.IsAny<int>())).Returns((int i) => products.Single(x => x.ProductId == i));


            //Here we are going to mock repository Delete method
            mock1.Setup(m => m.Delete(It.IsAny<Product>())).Returns((Product target) =>
            {

                var original = products.FirstOrDefault( q => q.ProductId == target.ProductId);

                if (original == null)
                {
                    return false;
                }

                products.Remove(target);

                return true;
            });
         
            //Now we have our repository ready for property injection


            //Here we are going to mock our IUnitOfWork
            Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();


            //Here we are going to inject our repository to the property
            mock.Setup(m => m.ProductRepository).Returns(mock1.Object);


            //Now our UnitOfWork is ready to be injected to the service
            //Here we inject UnitOfWork to constractor of our service
            ProductService productService = new ProductService(mock.Object);

            //Act

            productService.DeleteProduct(6);
            var result = products.FirstOrDefault(t => t.ProductId == 6);
            //Assert
            Assert.IsNull(result);
            Assert.IsTrue(products.Count ==5);

        }


        [TestMethod]
        public void Can_Find_By_Id()
        {
            //Arrange
            List<Product> products = new List<Product>()
                                         {
                                             new Product(){Description="P1",ProductId=1,ProductName="p1Name"},
                                             new Product(){Description="P2",ProductId=2,ProductName="p2Name"},
                                             new Product(){Description="P3",ProductId=3,ProductName="p3Name"},
                                             new Product(){Description="P4",ProductId=4,ProductName="p4Name"},
                                             new Product(){Description="P5",ProductId=5,ProductName="p5Name"},
                                             new Product(){Description="P6",ProductId=6,ProductName="p6Name"}
                                         };
            Mock<IGenericRepository<Product>> mock1 = new Mock<IGenericRepository<Product>>();


            //Here we are going to mock repository FindById Method
            mock1.Setup(m => m.FindById(It.IsAny<int>())).Returns((int i) => products.Single(x => x.ProductId == i));


            //Now we have our repository ready for property injection

            //Here we are going to mock our IUnitOfWork
            Mock<IUnitOfWork> mock = new Mock<IUnitOfWork>();

            //Here we are going to inject our repository to the property
            mock.Setup(m => m.ProductRepository).Returns(mock1.Object);

            //Now our UnitOfWork is ready to be injected to the service
            //Here we inject UnitOfWork to constractor of our service
            ProductService productService = new ProductService(mock.Object);


            //Act

            var result = productService.GetProduct(6);
            var expected = products.Single(t => t.ProductId == 6);

            //Assert

            Assert.AreEqual(expected,result);
        }
    }

 

2.     Implementing Controller unit test

In implementing test on your controller you can achieve UI Test simply, for this purpose I have created sample tests as shown below.

 

Controller Unit Tests
    // ProductControllerTest.cs
    [TestClass]
    public class ProductControllerTest
    {
       [TestMethod]
        public void Can_Paginate()
       {
           //Arrange
           Mock<IProductService> mock= new Mock<IProductService>();
           var products = new List<Product>();
          
           mock.Setup(m => m.GetAllProduct()).Returns((new Product[]
                                                          {
                                                              new Product(){ProductId=1,ProductName = "P1"} ,
                                                              new Product(){ProductId=2,ProductName = "P2"} ,
                                                              new Product(){ProductId=3,ProductName = "P3"} ,
                                                              new Product(){ProductId=4,ProductName = "P4"} ,
                                                              new Product(){ProductId=5,ProductName = "P5"} 
                                                          }).ToList());
    
           ProductController controller=new ProductController(mock.Object);


           controller.PageSize = 3;

           //Act
           ProductListViewModel result = (ProductListViewModel)controller.Index(2).Model;

           //Assert
           Product[] prodArray = result.Products.ToArray();
           Assert.IsTrue(prodArray.Length==2);
           Assert.AreEqual(prodArray[0].ProductName,"P4");
           Assert.AreEqual(prodArray[1].ProductName,"P5");
       }


        [TestMethod]
        public void Can_Generate_Page_Links()
        {
            //Arrange -define an Html helper -we need to do this
            //in order to apply the extension method
            HtmlHelper myHelper = null;


            //Arrange -create PagingInfo data
            PagingInfo pagingInfo = new PagingInfo()
                                        {
                                            CurrentPage = 2,
                                            TotalItems = 28,
                                            ItemsPerPage = 10
                                        };


            //Arrange -set up the delegate using a lamda expression
            Func<int, string> pageUrlDelegate = i => "Page" + i;


            //Act
            MvcHtmlString result = myHelper.PageLinks(pagingInfo, pageUrlDelegate);

            //Assert
            Assert.AreEqual(result.ToString(),@"<a href=""Page1"">1</a>"
                +@"<a class=""selected"" href=""Page2"">2</a>"+
                @"<a href=""Page3"">3</a>");
        }


        [TestMethod]
        public void Can_Send_Pagination_View_Model()
        {
            Mock<IProductService> mock = new Mock<IProductService>();
         
            mock.Setup(m => m.GetAllProduct()).Returns((new Product[]
                                                          {
                                                              new Product(){ProductId=1,ProductName = "P1"} ,
                                                              new Product(){ProductId=2,ProductName = "P2"} ,
                                                              new Product(){ProductId=3,ProductName = "P3"} ,
                                                              new Product(){ProductId=4,ProductName = "P4"} ,
                                                              new Product(){ProductId=5,ProductName = "P5"} 
                                                          }).ToList());


            ProductController controller = new ProductController(mock.Object);

            controller.PageSize = 3;

            //Act
            ProductListViewModel result = (ProductListViewModel) controller.Index(2).Model;

            //Assert
            PagingInfo pagingInfo = result.PagingInfo;
            Assert.AreEqual(pagingInfo.CurrentPage,2);
            Assert.AreEqual(pagingInfo.ItemsPerPage,3);
            Assert.AreEqual(pagingInfo.TotalItems,5);
            Assert.AreEqual(pagingInfo.TotalPages,2);
        }

    }