我试图围绕单元测试,我遇到了一个我不确定的行为:
“可以备份库存”
基本上,“库存”表被复制到“InventoryHistory”表,并给出备份发生时的时间戳(“HistoryDate”).
这是备份库存的代码:
DateTime historyDate = DateTime.Now;
MyDataContext db = new MyDataContext();
db.GetTable<InventoryHistory>().InsertAllOnSubmit(
db.GetTable<Inventory>()
.Select(i => new InventoryHistory
{
ID = i.ID,
ItemName = i.ItemName,
/* etc, etc, etc */
HistoryDate = historyDate
})
);
我的问题是:
>应该/可以将此行为分解为更小的可单元测试部件吗?
>由于我正在针对专用测试数据库进行测试,我是否应该使用模拟工具并遵循任何“存储库”的抽象工厂模式?
最佳答案 我要问的问题是,这真的是一个单元测试吗?单元测试将考虑模拟表< TEntity>实例,因为我们不关心实际数据,而是创建项目的机制是正确的.
在上面的代码片段中,您似乎是自己单元测试Linq方法,而不是您自己编写的任何特定代码.
至于你的上一个问题,模拟的一个基本错误就是假设在模拟时要测试什么.通常,您会模拟要测试的类型所消耗的内容.例如.:
public ICalculatorService
{
int Add(int a, int b);
}
[Test]
public void CannAdd()
{
var mock = Mock<ICalculatorService();
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.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<ICalculatorService();
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>()))
.Returns(100);
var calculator = new Calculator(mock.Object);
Assert(calculator.Add(1, 2) == 100); // Correct
}
这更像是它(虽然是一个简单的例子).我现在正在测试计算器消费者本身,而不是耗材.在您的示例中,即使您在模拟DataContext以返回Table< TEntity>的虚拟实例,您会获得什么真正的好处?
实际上你可能会创建一个存储库,例如一个IInventoryRepository,并创建该存储库的使用者(可以是域模型,控制器等).然后通过测试,您将模拟该存储库,并测试您的消费者.