Unit
tests should be run in isolation. Meaning, a test method should not have to
rely on database connections or other external dependencies being available. To accomplish
this, the repository (or other data access) class used by a service must be mocked and injected using
the service constructor. Review this sample code:
[TestMethod] public void GetByID_Test() { var orderCode = "TestOrder"; //Create a mock repository, and specify that the GetByID method always //returns an Order object with a given order code var mock = new Mock<IOrderRepository>(); mock.Setup(m => m.GetByID(It.IsAny<int>())).Returns ( new Company.DataAccess.Order{OrderCode = orderCode} ); //Inject the mock repository into the service using constructor var orderService = new OrderService(mock.Object); //Call the service method var order = orderService.GetById(4); Assert.AreEqual(order.OrderCode, orderCode, string.Format("OrderCode {0} doesn't match the expected value {1}", order.OrderCode, orderCode)); }
All
this code is doing is creating a "fake" repository using the
interface, then setting up the method used by the "GetByID" service method that always returns the same value. If
desired, methods can be faked to return different values based on the parameter
passed in. Ideally, the mock repository setup would be contained in a common
setup method, and each and every repository method would be setup with expected
values, so it could be reused in each test method.
Yes,
this adds time to your development cycle, but it makes your test methods more
precise, isolating only the code it's meant to test, eliminating reliance on
dependencies such as databases and any other "external" dependency.
No comments:
Post a Comment