简体   繁体   English

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

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

I was reading a book and below is some code:我正在读一本书,下面是一些代码:

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

The author says Customer is the SUT and Store is the collaborator作者说CustomerSUTStore合作者

I'm a little bit confused here, the assert phase also test the Store, isn't that Store is also a SUT?我这里有点迷糊,assert阶段也测试了Store,那Store不也是一个SUT吗?

The SUT stands for System Under Test , which practically means that object against which you perform your act . SUT代表System Under Test ,这实际上意味着您执行操作的object

In the assert phase you are checking your assumptions, where there is an actual and an expected value.在断言阶段,您正在检查您的假设,其中有actual值和expected值。 You are validating the actual against the expected.您正在根据预期验证实际情况。


In the above mentioned code the Assert.Equal receives first the expected value and then the actual.在上面提到的代码中, Assert.Equal首先接收期望值,然后是实际值。 And here the actual value is coming from the store.而这里的实际价值来自商店。 It is good because the Purchase method call indicates that the inventory should shrink because a purchase has been placed这很好,因为 Purchase 方法调用表明库存应该减少,因为已经进行了购买

Happy path:快乐之路:
- Given an inventory with 10 items - 给定一个有 10 件物品的库存
- When I purchase 5 items - 当我购买 5 件商品时
- Then 5 items will remain - 然后将保留 5 个项目

Unhappy path:不开心的路:
- Given an inventory with 10 items - 给定一个有 10 件物品的库存
- When I try to buy 15 items - 当我尝试购买 15 件商品时
- Then my purchase will fail and the inventory remains as it was. - 然后我的购买将失败,库存保持原样。

To better emphasise the intent you could rewrite the test like this:为了更好地强调意图,您可以像这样重写测试:

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

As Peter Csala points out, SUT stands for System Under Test.正如 Peter Csala 所指出的, SUT代表被测系统。 I can see how this can be confusing if you interpret the word system to mean 'an arrangement of things'.如果您将系统一词解释为“事物的安排”,我可以看到这会令人困惑。 Under such an interpretation, I can see how the store could also be viewed as part of a wider system.在这样的解释下,我可以看到商店也可以被视为更广泛系统的一部分。

That is, however, not the way the term SUT is usually interpreted.然而,这不是 SUT 一词通常被解释的方式。 Normally, the term denotes the unit you directly interact with.通常,该术语表示您直接与之交互的单位。 In object-oriented programming, this is usually an object on which you call a method.在面向对象编程中,这通常是您调用方法的 object。

I usually name test variables according to the roles they play in the test.我通常根据它们在测试中扮演的角色来命名测试变量。 Thus, I typically name the SUT variable sut .因此,我通常将 SUT 变量命名为sut

Also, now that we're at it, 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 .另外,既然我们已经完成了, 我发现没有必要在空行已经使结构清晰时使用注释来表示排列、动作和断言阶段

The following is closer to how I'd write the tests.以下更接近我编写测试的方式。

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

This makes it unambiguously clear which object is the SUT.这清楚地表明哪个 object 是 SUT。 It's the variable named sut .它是名为sut的变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM