簡體   English   中英

Linq 方法的單元測試

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM