如何在NUnit中编写集成测试?

13
我们是两名撰写学士论文的学生,开发了一个Windows应用程序,旨在协助餐厅进行各种通信流程。基本上,它可以从客人发送订单到服务结束期间呈现有关订单的信息。
在开发期间,我们忽略了测试,但现在决定编写单元测试。尽管如此,我们发现我们现在能够为我们的系统编写的最合适的测试是集成测试,因为我们类中的所有方法都通过LINQ to SQL绑定到SQL存储过程。我们知道可以使用存根来虚拟对数据库的依赖性,但当我们的数据库已经与所有功能一起实现时,我们认为将多个方法作为集成测试一起测试将更有价值。
如下所示的代码,我们已经尝试遵循单元测试的指南,但这是编写集成测试的正确方式吗?
[Test]
public void SendTotalOrder_SendAllItemsToProducer_OneSentOrder()
{
    //Arrange
    Order order = new Order();
    Guest guest = new Guest(1, order);
    Producer producer = new Producer("Thomas", "Guldborg", "Beverage producer");            
    DataGridView dataGridView = new DataGridView { BindingContext = new BindingContext() };
    order.MenuItemId = 1;
    order.Quantity = 1;

    //Act
    guest.AddItem();
    dataGridView.DataSource = guest.SendOrderOverview();
    guest.SendOrder(dataGridView);
    dataGridView.DataSource = producer.OrderOverview();
    var guestTableOrder = producer.OrderOverview()
        .Where(orders => orders.gtid == guest.GuestTableId)
        .Select(producerOrder => producerOrder.gtid) 
        .Single();

    //Assert
    Assert.That(guestTableOrder, Is.EqualTo(guest.GuestTableId));
}
2个回答

26

通常来说,编写单元测试/集成测试的方式是这样的。您需要遵循一些重要的指导方针:

  • 明确的 Act-Arrange-Assert 步骤
  • 测试名称描述了这些步骤(可能应该在结尾处添加类似于 "应该发送一个订单" 的内容,“应该”通常用于描述 Assert)。
  • 每个测试只有一个 Assert。

我认为您也会遵守其他指南:

  • 测试是独立的:它们不改变持久状态,因此不影响其他测试。
  • 测试真实的使用情况:不安排违反业务逻辑的组合,不要执行不可能的操作。或者:模拟真实应用程序。

但是,我还看到了一些令人担忧的事情。

  • 不清楚您测试了哪个“行动”。我认为某些“行动”属于安排步骤。

  • producer.OrderOverview() 这样的方法让我怀疑域对象执行数据库交互。如果是这样,那么这将违反持久性无知。我认为应该有一个呈现此方法的服务(但请参见下文)。

  • 不清楚为什么测试需要 dataGridView.DataSource = producer.OrderOverview();。如果是这样,这只会加重最严重的一点:

  • 业务逻辑和UI是交织在一起的!

    • guest.SendOrderOverview()producer.OrderOverview() 这样的方法是有问题的:为什么域对象要知道如何呈现其内容?这是由 Presenter (MVP)、Controller (MVC) 或 View Model (MVVM) 负责的事情。
  • guest.SendOrder(dataGridView)这样的方法是有害的。 它将领域层与UI框架绑定在一起,这种固定的依赖关系已经足够恶劣了,但当然你还需要在此方法内部获取来自网格视图的值。所以业务逻辑需要深入了解某些UI组件,这违反了告诉 - 不要问原则。guest.SendOrder应该具有简单的参数,告诉它如何执行其任务,而领域不应引用任何UI框架。
  • 您真的应该解决后一个问题。 使您的目标是在没有与DGV的任何交互的情况下运行此测试。


    非常感谢您详尽的回答!这非常受到赞赏!我现在已经实施了您建议的大部分要点。实际上,这是我的第一个集成测试,因此获得这种全面的解释在做什么和不做什么方面非常有价值 :-) - Guldborg92

    0

    如果你在类中继续绑定 SQL,你的测试不是一个大问题。

    当程序逻辑非常简单时,你可以使用这种方法。但是我建议你学习仓储模式,因为逻辑变得更加复杂。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接