如果返回true表示远程链接成功建立并且已经成功打开,如果返回false表示链接失败;那么在每一个用例代码中,只要使用到了IServiceConnection接口都会需要Mock接口的Open方法;
[TestMethod] public void OrderService_GetOrders_NormalFlows() { mockServiceConnection.Open().Returns(true); mockServiceConnection.Close().Returns(true); OrderService testOrderService = new OrderService(mockServiceConnection, mockServiceReader, mockServiceWriter); bool testResult = testOrderService.GetOrders("10293884"); Assert.AreEqual(true, testResult); } [TestMethod] public void OrderService_GetOrders_OrderIdIsNull() { mockServiceConnection.Open().Returns(true); mockServiceConnection.Close().Returns(false); OrderService testOrderService = new OrderService(mockServiceConnection, mockServiceReader, mockServiceWriter); bool testResult = testOrderService.GetOrders(string.Empty); Assert.AreEqual(false, testResult); } [TestMethod] public void OrderService_GetOrders_NormalFlows() { mockServiceConnection.Open().Returns(true); mockServiceConnection.Close().Returns(true); OrderService testOrderService = new OrderService(mockServiceConnection, mockServiceReader, mockServiceWriter); bool testResult = testOrderService.GetOrders("10293884"); Assert.AreEqual(true, testResult); } [TestMethod] public void OrderService_GetOrders_OrderIdIsNull() { mockServiceConnection.Open().Returns(true); mockServiceConnection.Close().Returns(false); OrderService testOrderService = new OrderService(mockServiceConnection, mockServiceReader, mockServiceWriter); bool testResult = testOrderService.GetOrders(string.Empty); Assert.AreEqual(false, testResult); } |
类似这样的代码会很多,如果这个时候我们需要每次都在用例中对三个接口都进行类似的重复代码也算是一种地效率的重复劳动,并且在后面的改动中会很费事;所以这个时候抽象出来的基类就派上用场了,我们可以将构建接口的逻辑代码放入基类中进行统一构造;
public abstract class ServiceBaseUnitTestClass { protected IServiceConnection mockServiceConnection = Substitute.For<IServiceConnection>(); protected IServiceReader mockServiceReader = Substitute.For<IServiceReader>(); protected IServiceWriter mockServiceWriter = Substitute.For<IServiceWriter>(); protected void InitMockServiceConnection() { this.mockServiceConnection.Open().Returns(true); this.mockServiceConnection.Close().Returns(true); } } this.InitMockServiceConnection(); OrderService testOrderService = new OrderService(mockServiceConnection, mockServiceReader, mockServiceWriter); public abstract class ServiceBaseUnitTestClass { protected IServiceConnection mockServiceConnection = Substitute.For<IServiceConnection>(); protected IServiceReader mockServiceReader = Substitute.For<IServiceReader>(); protected IServiceWriter mockServiceWriter = Substitute.For<IServiceWriter>(); protected void InitMockServiceConnection() { this.mockServiceConnection.Open().Returns(true); this.mockServiceConnection.Close().Returns(true); } } this.InitMockServiceConnection(); OrderService testOrderService = new OrderService(mockServiceConnection, mockServiceReader, mockServiceWriter); |
2.1.3】公用的Mock数据
说到Mock数据,其实需要解释一下,准确点讲是Mock时需要用到的测试数据,它是碎片化的简单的测试数据;它也同样存在着和2.1.2】小结的修改问题,实践告诉我单元测试代码在整个开发周期中最易被修改,当我们简单的修改一个逻辑之后就需要面临着大面积的单元测试代码修改而测试数据修改占比重最大;
因为测试数据相对没有灵活性,但是测试数据的结构易发生由需求带来的变化;比如实体的属性类型,在我们编写实体测试数据的时候我们用的是String,一段时间过后,实体发生变化很正常;领域模型在开发周期中被修改的次数那是无法估计,因为我们的项目中是需要迭代重构的,我们需要重构来为我们的项目保证最高的质量;
所以单元测试修改的次数和重构的次数应该是成1:0的这样的比例,修改的范围那就不是1:10了,有时候甚至是几何的倍数;
OrderService中的AddOrder方法:
public bool AddOrder(Order order) { if (string.IsNullOrWhiteSpace(order.OrderId)) return false; return true; } public bool AddOrder(Order order) { if (string.IsNullOrWhiteSpace(order.OrderId)) return false; return true; } OrderService_AddOrder测试代码: [csharp] view plaincopyprint? [TestMethod] public void OrderService_AddOrder_NormalFlows() { this.InitMockServiceConnection(); OrderService testOrderService = new OrderService(this.mockServiceConnection, this.mockServiceReader, this.mockServiceWriter); Order testOrder = new Order() { OrderId = "123456", SubmitDT = DateTime.Now }; bool testResult = testOrderService.AddOrder(testOrder); Assert.AreEqual(true, testResult); } [TestMethod] public void OrderService_AddOrder_OrderIdIsNull() { this.InitMockServiceConnection(); OrderService testOrderService = new OrderService(this.mockServiceConnection, this.mockServiceReader, this.mockServiceWriter); Order testOrder = new Order() { OrderId = string.Empty, SubmitDT = DateTime.Now }; bool testResult = testOrderService.AddOrder(testOrder); Assert.AreEqual(false, testResult); } [TestMethod] public void OrderService_AddOrder_NormalFlows() { this.InitMockServiceConnection(); OrderService testOrderService = new OrderService(this.mockServiceConnection, this.mockServiceReader, this.mockServiceWriter); Order testOrder = new Order() { OrderId = "123456", SubmitDT = DateTime.Now }; bool testResult = testOrderService.AddOrder(testOrder); Assert.AreEqual(true, testResult); } [TestMethod] public void OrderService_AddOrder_OrderIdIsNull() { this.InitMockServiceConnection(); OrderService testOrderService = new OrderService(this.mockServiceConnection, this.mockServiceReader, this.mockServiceWriter); Order testOrder = new Order() { OrderId = string.Empty, SubmitDT = DateTime.Now }; bool testResult = testOrderService.AddOrder(testOrder); Assert.AreEqual(false, testResult); } |