[英]Unit Testing for Linq Method
我有一个必须为其编写单元测试的方法。 此方法使用数据库上下文从数据库中检索详细信息。
现在我正在想办法模拟这个数据库上下文并测试剩余的 LINQ 代码。
同样,我还有其他方法,这些方法具有一些逻辑和一些 LINQ 查询,我也想对它们进行单元测试。
public class OrderService
{
private DataContext _context;
public OrderService(DataContext context)
{
_context = context;
}
public int OrderCount(int orderId)
{
var count = _context.Orders.Where(x=>x.orderId==orderId).ToList().Count;
}
}
我应该如何处理这种情况?
这是开发人员面临的常见情况,但关于这方面的信息还不多。 任何建议,将不胜感激。
我的建议是将您的数据在数据库中的事实与您想要获取数据的方式分开。
换句话说:您的 LINQ 方法应该将IQueryable<...>
作为输入。 不是 DbContext。
除了这将使您的单元测试变得轻而易举之外,它还允许您重用 LINQ 处理来自不同来源的数据,例如不同的数据库,或 CSV 文件,或 XML,或者也许只是来自字典。
我创建了一个扩展方法。 如果您不熟悉扩展方法,请考虑阅读扩展方法揭秘
public static int Count(this IQueryable<Order> orders, int orderId)
{
return orders.Where(order=>order.orderId==orderId).Count();
}
用法:
int orderId = this.ReadOrderId();
using (var dbContext = new MyOrderContext(...))
{
return dbContext.Orders.Count(orderId);
}
也许CountByOrderId
是一个更好的名字。
对于您的单元测试,例如测试空订单集合的 CountByOrderId:
int orderId = 4;
var emptyOrderCollection = Enumerable.Empty<Order>();
int orderCount = emptyOrderCollection.CountByOrderId(orderId);
Assert.AreEqual(..., orderCount);
顺便说一下,您是否注意到我删除了ToList
? 先创建一个List,然后只使用里面的元素个数,然后把list扔掉,有点浪费处理能力。
如果你想让你的计数方法更通用,例如也计算具有特定价格的产品,或特定出生年份的学生:
public static CountByProperty<TSource, TPropery>(this IQueryable<TSource> source,
Expression<Func<TSource,TProperty>> propertySelector,
TProperty value)
{
return source.Where(s=>propertySelector(s)==value).Count();
}
用法:
return dbContext.Orders.CountByProperty(order => order.OrderId, 4);
或者计算价格恰好为 1.00 美元的产品:
return dbContext.Products.CountByProperty(product => product.Price, 1.00);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.