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

How to determine which is a SUT and which is a collaborator in unit testing?

我正在看书,下面是一些代码:

[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));
}

作者说 CustomerSUTStore合作者

我这里有点懵,assert阶段也测试Store,Store不也是一个SUT吗?

SUT 代表 System Under Test,这实际上意味着您执行 act 所针对的对象。

在断言阶段,您正在检查您的假设,其中有一个 actual 和一个 expected 值。您正在根据预期验证实际情况。


在上面提到的代码中,Assert.Equal 首先接收预期值,然后接收实际值。这里的实际价值来自商店。 这很好,因为 Purchase 方法调用表明库存应该减少,因为已经购买了

幸福之路:
- 给定一个包含 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));
}

正如 Peter Csala 指出的那样,SUT 代表被测系统。如果您将 system 一词解释为 'an arrangement of things',我可以理解这会造成怎样的混淆。在这样的解释下,我可以看到如何将商店也视为更广泛系统的一部分。

然而,这不是术语 SUT 的通常解释方式。通常,该术语表示您直接与之交互的单位。在面向对象的编程中,这通常是您调用方法的对象。

我通常根据它们在测试中扮演的角色来命名测试变量。因此,我通常将 SUT 变量命名为 sut.

此外,既然我们已经开始了,I don't find it necessary to use comments to denote the arrange, act, and assert phases when blank lines already make that structure clear

以下更接近我编写测试的方式。

[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.

的变量