单元测试使用LINQ修炼到SQL [英] Unit Testing practice with Linq to SQL

查看:95
本文介绍了单元测试使用LINQ修炼到SQL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想换行我的头周围的单元测试,和我遇到了我不能确定的行为:

可以备份库存

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

这里的code为后盾机盘点:

 日期时间historyDate = DateTime.Now;
        MyDataContext DB =新MyDataContext();

        db.GetTable< InventoryHistory>()InsertAllOnSubmit(。
            db.GetTable<库存>()
                。选择(I =>新建InventoryHistory
                {
                    ID = i.ID,
                    =了itemname i.ItemName,
                    / *等,等,等* /
                    HistoryDate = historyDate

                })
        );
 

我的问题是:

  1. 如果/可这种行为被分解成更小的单元测试的部分?

  2. 由于我对测试的专用测试数据库,我应该用讽刺的工具并按照抽象工厂模式的任何资料库?

解决方案

我要问的是,现在的问题是这真的是一个单元测试?单元测试将考虑嘲笑表< TEntity> 情况下,因为我们不关心实际的数据,而这创造了项目的机制是正确的。

在上面的代码片段,看来你是单元测试的LINQ的方法本身,没有任何具体的code您自己编写。

至于你的最后一个问题,与嘲弄取得了根本性的错误之一是的什么的以嘲讽的时候测试的假设。通常情况下,你会嘲笑你所要测试的类型消耗的东西。例如:

 公共ICalculatorService
{
  INT添加(INT A,INT B);
}

[测试]
公共无效CannAdd()
{
  VAR模拟=模拟< ICalculatorService();
  mock.Setup(米=> m.Add(It.IsAny&其中; INT>(),It.IsAny&其中; INT>()))
      .Returns(100);

  VAR的服务= mock.Object;
  断言(service.Add(1,2)== 100); //不正确
}
 

以上是一个毫无意义的测试,因为我测试了它返回正是我已经告诉它。我没有测试的起订量架构在这里,我需要测试我的code,所以我需要被测试的消费者:

 公共类计算器
{
  私人只读ICalculatorService _service;

  公共计算器(ICalculatorService服务)
  {
    _Service =服务;
  }

  公众诠释添加(INT A,INT B)
  {
    返回_service.Add(A,B);
  }
}

[测试]
公共无效CannAdd()
{
  VAR模拟=模拟< ICalculatorService();
  mock.Setup(米=> m.Add(It.IsAny&其中; INT>(),It.IsAny&其中; INT>()))
      .Returns(100);

  VAR计算器=新计算器(mock.Object);
  断言(calculator.Add(1,2)== 100); // 正确
}
 

这是更喜欢它(尽管一个简单的例子)。我现在测试计算器消费本身,而不是消耗品。在你的榜样,即使你会嘲笑你的DataContext返回的虚拟实例表< TEntity> ,你得到什么真正的实惠

实事求是你可能会创建一个存储库,如一个 IInventoryRepository ,并创建一个消费者的资料库中(可能是一个域模型,控制器等)。然后通过测试,你会嘲笑的资源库,并测试你的消费者。

I'm trying to wrap my head around unit testing, and I've encountered a behavior that I'm unsure of:

"Can Backup Inventory"

Basically, the "Inventory" table is copied to the "InventoryHistory" table, and given a time-stamp of when the backup occurred ("HistoryDate").

Here's the code for backing-up inventory:

        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

                })
        );

My questions are:

  1. Should/Can this behavior be broken down into smaller unit-testable parts?

  2. Since I am testing against a dedicated test database, should I be using a mocking tool and following the abstract factory pattern for any "repositories"?

解决方案

The question I would ask is that is this really a unit test? A unit test would consider mocked Table<TEntity> instances, because we're not concerned with the actual data, rather that the mechanism of creating the items is correct.

In your snippet above, it seems that you are unit testing the Linq methods themselves, not any specific code you have written yourself.

As for your last question, one of the fundamental mistakes made with mocking is the assumption of what to test when mocking. Typically you would be mocking a something consumed by the type you want to test. E.g.:

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
}

The above is a pointless test, because I am testing that it is returning exactly what I have told it to. I'm not testing the Moq framework here, I need to test my code, so I would need to be testing the consumer:

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
}

That's more like it (although a simplistic example). I am now testing the Calculator consumer itself, not the consumable. In your example, even if you were mocking your DataContext to return dummy instances of Table<TEntity>, what real benefits do you get?

Realistically you'd probably create a repository, e.g. an IInventoryRepository, and create a consumer of that repository (could be a domain model, a controller, etc). Then through testing, you'd mock that repository, and test your consumer.

这篇关于单元测试使用LINQ修炼到SQL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆