如何确定在单元测试中哪个是 SUT,哪个是协作者?

4

我正在读一本书,以下是一些代码:

[Fact]
public void Purchase_succeeds_when_enough_inventory()
{
    // Arrange
    var store = new Store();
    store.AddInventory(Product.Shampoo, 10);
    var customer = new Customer();

    // Act
    bool success = customer.Purchase(store, Product.Shampoo, 5);

    // Assert
    Assert.True(success);
    Assert.Equal(5, store.GetInventory(Product.Shampoo));
}

[Fact]
public void Purchase_fails_when_not_enough_inventory()
{
    // Arrange
    var store = new Store();
    store.AddInventory(Product.Shampoo, 10);
    var customer = new Customer();

    // Act
    bool success = customer.Purchase(store, Product.Shampoo, 15);

    // Assert
    Assert.False(success);
    Assert.Equal(10, store.GetInventory(Product.Shampoo));
}

作者说客户被测系统(SUT),而商店则是协作者

我有点困惑,断言阶段也测试了商店,那么商店不也是被测系统吗?

2个回答

4

SUT 即被测试系统,实际上是指针对其执行 行动 的对象。

在断言阶段,您正在检查您的假设,其中存在一个 actual 和一个 expected 值。您正在验证实际值与预期值之间的关系。


在上述代码中,Assert.Equal 首先接收预期值,然后是实际值。这里实际值来自存储。 这很好,因为购买方法调用表示库存应该减少,因为已经下了订单。

正向路径:
- 假设有10件商品
- 当我购买5件商品时
- 那么就会剩下5件商品

非正向路径:
- 假设有10件商品
- 当我尝试购买15件商品时
- 那么我的购买将失败,库存将保持不变。

为了更好地强调意图,您可以像这样重写测试:

[Fact]
public void Purchase_succeeds_when_enough_inventory()
{
    // Arrange
    const int initialItemCount = 10;
    const int intededPurchaseCount = 5;

    var store = new Store();
    var product = Product.Shampoo;
    store.AddInventory(product, initialItemCount);
    var customer = new Customer();

    // Act
    bool isSuccess = customer.Purchase(store, product, intededPurchaseCount );

    // Assert
    Assert.True(isSuccess);
    var expectedInventoryCount = initialItemCount - intededPurchaseCount;
    Assert.Equal(expectedInventoryCount, store.GetInventory(product));
}

[Fact]
public void Purchase_fails_when_not_enough_inventory()
{
    // Arrange
    const int initialItemCount = 10;
    const int intededPurchaseCount = 15;

    var store = new Store();
    var product = Product.Shampoo;
    store.AddInventory(product, initialItemCount);
    var customer = new Customer();

    // Act
    bool isSuccess = customer.Purchase(store, product, intededPurchaseCount);

    // Assert
    Assert.False(isSuccess);
    Assert.Equal(initialItemCount, store.GetInventory(product));
}

3
正如Peter Csala指出的那样,SUT代表System Under Test,如果你将单词system解释为“一系列事物的安排”,我可以理解这可能会引起混淆。在这种情况下,我可以看到商店也可以被视为更广泛系统的一部分。
然而,这不是SUT通常被解释的方式。通常,该术语表示您直接交互的单元。在面向对象编程中,通常是您调用方法的对象。
我通常根据测试中它们扮演的角色来命名测试变量。因此,我通常将SUT变量命名为sut
另外,既然我们谈到了这个问题,我认为不必使用注释来表示安排(arrange),执行(act)和断言(assert)阶段,因为空行已经清晰地展现了这种结构。 以下更接近我编写测试的方式。
[Fact]
public void Purchase_succeeds_when_enough_inventory()
{
    var store = new Store();
    store.AddInventory(Product.Shampoo, 10);
    var sut = new Customer();

    bool success = sut.Purchase(store, Product.Shampoo, 5);

    Assert.True(success);
    Assert.Equal(5, store.GetInventory(Product.Shampoo));
}

[Fact]
public void Purchase_fails_when_not_enough_inventory()
{
    var store = new Store();
    store.AddInventory(Product.Shampoo, 10);
    var sut = new Customer();

    bool success = sut.Purchase(store, Product.Shampoo, 15);

    Assert.False(success);
    Assert.Equal(10, store.GetInventory(Product.Shampoo));
}

这使得SUT对象的身份非常明确。它就是名为sut的变量。


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