.NET重构?单元测试重构(2)
作者:网络转载 发布时间:[ 2013/10/11 14:19:01 ] 推荐标签:
这是两个用例,用来对AddOrder方法进行测试,里面都包含了一条Order testOrder = new Order() 这样的测试数据的构造;Order实体是一个比较简单的对象,属性也只有两个,但是真实环境中不会这么简单,会有几十个字段都需要进行测试验证,再加上N多个用例,会使相同的代码变的很多;
那么我们同样需要将这部分的代码提取出来放到基类中去,适当的留有空间让用例中修改的特殊的字段;
完整的实体构造:
Order testOrder = this.InitNormalOrder();
Order testOrder = this.InitNormalOrder();
测试OrderId为空的逻辑,需要手动设置为String.Empty:
<STRONG>Order testOrder = this.InitNormalOrder();
testOrder.OrderId = string.Empty; </STRONG>
Order testOrder = this.InitNormalOrder();
testOrder.OrderId = string.Empty; 这样慢慢的会形成抗变化的测试代码结构,尽管一开始很别扭,将一些直观的对象提取出来放入一眼看不见的地方是有点不太舒服,但是长远看来值得这么做;
3】LINQ表达式的重构写法(将必要的LINQ写成普通的Function穿插在LINQ表达式中)
在使用LINQ语法编写代码的时候,现在发现大的问题是单元测试不太方便,LINQ写起来很方便,确实是个很不错的编程思想,在面对集合类型的操作时确实是无法形容的优雅,但是面对单元测试的问题需要解决才行,所以需要我们平衡一下在什么情况下需要将LINQ表达式替换成普通的Function来支持;
LINQ在面对集合类型的时候,能发挥很大的作用;不仅在Linq to Object中,在其他的Linq to Provider中都能在LINQ中找到了合适的使用之地;比如在对远程Service进行LINQ设计的时候,我们都是按照这样的方式进行编写,但是怕LINQ中带有逻辑判断的表达式,这个时候会在单元测试中总是无法覆盖到的情况出现,所以需要将它提取出来使用普通的函数进行替代;
我们来继续看一下如果使用提取出来的函数解决链式的判断,还是使用上面的OrderService为例:
public Order SelectByOrderId(string orderId)
{
List<Order> orders = new List<Order>()
{
new Order(){ OrderId="123", SubmitDT=DateTime.Now.AddDays(1)},
new Order(){ OrderId="234"}
};
var list = orders.Where(order => order.OrderId == orderId && order.SubmitDT > DateTime.Now);
if (list.Count() > 0)
return list.ToList()[0];
return null;
}
public Order SelectByOrderId(string orderId)
{
List<Order> orders = new List<Order>()
{
new Order(){ OrderId="123", SubmitDT=DateTime.Now.AddDays(1)},
new Order(){ OrderId="234"}
};
var list = orders.Where(order => order.OrderId == orderId && order.SubmitDT > DateTime.Now);
if (list.Count() > 0)
return list.ToList()[0];
return null;
}
这是一个根据OrderId获取Order实例的方法,纯粹为了演示;首先构造了一个测试集合,然后使用了Where扩展方法来选择集合中满足条件的Order;我们的重点是Where中的条件,条件的第一个表达式很简单而第二个表达式是SubmitDT必须大于当前的日期,还会有很多类似这样的判断,这样测试起来很困难,而且很难维护,所以我们有必要将他们提取出来;
public Order SelectByOrderId(string orderId)
{
List<Order> orders = new List<Order>()
{
new Order(){ OrderId="123", SubmitDT=DateTime.Now.AddDays(1)},
new Order(){ OrderId="234"}
};
var list = orders.Where(order => IfOrderSubmitAndOrderId(order, orderId));
if (list.Count() > 0)
return list.ToList()[0];
return null;
}
private bool IfOrderSubmitDt(Order order)
{
return order.SubmitDT > DateTime.Now;
}
private bool IfOrderSubmitAndOrderId(Order order, string orderId)
{
return order.OrderId == orderId && this.IfOrderSubmitDt(order);
}
public Order SelectByOrderId(string orderId)
{
List<Order> orders = new List<Order>()
{
new Order(){ OrderId="123", SubmitDT=DateTime.Now.AddDays(1)},
new Order(){ OrderId="234"}
};
var list = orders.Where(order => IfOrderSubmitAndOrderId(order, orderId));
if (list.Count() > 0)
return list.ToList()[0];
return null;
}
private bool IfOrderSubmitDt(Order order)
{
return order.SubmitDT > DateTime.Now;
}
private bool IfOrderSubmitAndOrderId(Order order, string orderId)
{
return order.OrderId == orderId && this.IfOrderSubmitDt(order);
}
其实这很像企业架构模式中的规约模式,将规则对象化后能随便的控制他们,当然这里是提取出方法,如果是大型企业级项目对这些易变化的点是需要抽取出来的;
总之遇到这样的情况使用简单的提取方法的方式将复杂的逻辑提取出来,这也是《重构》中的重构策略的首要的模式;
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11