Linq to SQL的unit testing实践

我试图围绕unit testing,我遇到了一个我不确定的行为:

“可以备份库存”

基本上,“库存”表被复制到“InventoryHistory”表,并给出备份发生的时间戳(“HistoryDate”)。

这是备份库存的代码:

DateTime historyDate = DateTime.Now; MyDataContext db = new MyDataContext(); db.GetTable().InsertAllOnSubmit( db.GetTable() .Select(i => new InventoryHistory { ID = i.ID, ItemName = i.ItemName, /* etc, etc, etc */ HistoryDate = historyDate }) ); 

我的问题是:

  1. 应该/可以将此行为分解为更小的可unit testing部件吗?

  2. 由于我正在测试专用测试数据库,我应该使用模拟工具并遵循任何“存储库”的抽象工厂模式吗?

我要问的问题是,这真的是一个unit testing吗? unit testing会考虑模拟Table实例,因为我们不关心实际数据,而是创建项目的机制是正确的。

在上面的代码片段中,您似乎是自己unit testingLinq方法,而不是您自己编写的任何特定代码。

至于你的上一个问题,模拟的一个基本错误是假设在模拟时要测试什么。 通常,您会模拟要测试的类型所消耗的内容。 例如:

 public ICalculatorService { int Add(int a, int b); } [Test] public void CannAdd() { var mock = Mock m.Add(It.IsAny(), It.IsAny())) .Returns(100); var service = mock.Object; Assert(service.Add(1, 2) == 100); // Incorrect } 

以上是一个毫无意义的测试,因为我正在测试它正在返回我告诉它的内容。 我不是在这里测试Moq框架,我需要测试我的代码,所以我需要测试消费者:

 public class Calculator { private readonly ICalculatorService _service; public Calculator(ICalculatorService service) { _service = service; } public int Add(int a, int b) { return _service.Add(a, b); } } [Test] public void CannAdd() { var mock = Mock m.Add(It.IsAny(), It.IsAny())) .Returns(100); var calculator = new Calculator(mock.Object); Assert(calculator.Add(1, 2) == 100); // Correct } 

这更像是它(虽然是一个简单的例子)。 我现在正在测试Calculator消费者本身,而不是耗材。 在您的示例中,即使您在模拟DataContext以返回Table虚拟实例,您会获得什么真正的好处?

实际上,您可能会创建一个存储库,例如IInventoryRepository ,并创建该存储库的使用者(可能是域模型,控制器等)。 然后通过测试,您将模拟该存储库,并测试您的消费者。

对我来说这看起来像是一个相当primefaces的操作,没有多少机会将它分开。

unit testing不会影响数据库 – 即集成测试。 如果你想为此做一个好的unit testing,那么你将测试行为 – 在这种情况下,历史是在应该的时候备份的。

通过完全公开,我只是刚刚开始学习EF和LINQ以及测试它们的最佳方法,因此您可能会获得更多有关它们的有用信息,因此这些只是一般的测试答案。

1.除了以下方面,我无法看到一种可以进一步细分为unit testing的方法:

 ID = i.ID, ItemName = i.ItemName, /* etc, etc, etc */ HistoryDate = historyDate 

被重构为单独的方法进行unit testing,因为唯一的其他代码是LINQ调用,MS负责测试。

2.我认为您不能引入接缝来将其与抽象存储库工厂模式隔离,因为您正在调用datacontext。

我不确定你是否应该假装这个(因为你要对它进行测试将是一个模拟的正确 – 你测试的假,你没有测试的假是一个存根 )但是因为它正在调用在测试服务器中,您可以将其作为自动集成测试,因为该function涉及与数据存储的交互。

首先,您描述的方法看起来很简单,我不确定它是否需要任何unit testing。 但是,如果你想分解它,你可以这样做:

  1. 获取备份清单列表的提取方法

    IQueryable GetInventoryForBackup(此DataContext上下文){return context.GetTable(); }

  2. 提取方法将Inventory转换为InventoryHistory

    IEnumerable ToInventoryHistory(此IEnumerable数据,DateTime historyDate){return data.Select(i => new InventoryHistroy {ID = i.Id ….}

  3. 提取方法以保存InventoryHistory的序列

    void SaveHistory(IEnumerable data){dataContext.InsertAllOnSubmit(data); dataContext.SubmitChanges(); }

现在你有了很好的方法,你可以轻松编写unit testing。