代码之家  ›  专栏  ›  技术社区  ›  Titan

断言在编写单元测试时“什么都没发生”

  •  6
  • Titan  · 技术社区  · 7 年前

    在编写单元测试时,是否有一种简单的方法来确保没有意外发生?

    由于可能的副作用列表是无限的,因此添加大量断言以确保在每个步骤中都没有更改似乎是徒劳的,这混淆了测试的目的。

    我可能错过了一些框架特性或良好实践。
    我使用的是C#7。net 4.6,MSTest V1。

    编辑: 更简单的例子是测试viewmodel的setter,应该发生两件事:值应该更改,PropertyChanged事件应该引发。 这两件事很容易检查,但现在我需要确保其他属性值没有更改,没有引发其他事件,没有触摸系统剪贴板。。。

    5 回复  |  直到 7 年前
        1
  •  4
  •   Mark Benningfield    7 年前

    你错过了单元测试的要点。它们是“证据”。你无法从逻辑上证明一个否定的断言,所以即使尝试也没有意义。

    每个单元测试中的断言应该证明所需的行为已经完成。这就是全部。

    如果我们把这个问题简化为荒谬的话,每个单元测试都会要求我们断言被测试的功能没有引发热核战争。

    单元测试包括 您需要执行的唯一类型的测试。有功能测试、集成测试、可用性测试等。每种测试都有自己的重点。对于单元测试,重点是证明单个函数的预期行为。因此,如果函数应该完成两件事,只需断言这两件事都发生了,然后继续。

        2
  •  2
  •   ethane    6 年前

    确保没有“坏”或意外情况发生的选项之一是确保使用依赖注入和模拟的良好实践:

    [Test]
    public void TestSomething()
    {
        // Arrange
        var barMock = RhinoMocks.MockRepository.GenerateStrictMock<IBar>();
        var foo = new Foo(barMock);
        // Act
        foo.DoSomething();
        // Assert
        ...
    }
    

    在上述示例中,如果 Foo 意外接触 Bar ,这将导致异常(严格模拟),测试失败。这种方法可能不适用于所有测试用例,但可以作为其他潜在实践的良好补充。

        3
  •  2
  •   Link    7 年前

    对您的编辑进行一些补充:

    在里面 Test Driven Development 您只编写代码,只需通过测试即可。此外,您希望选择最简单的解决方案来实现此目标。

    也就是说,您很可能会从失败的单元测试开始。在您的情况下,您不会在一开始就得到一个失败的单元测试。

    如果你把它推到极限,你必须检查一下 format C:\ 当您要检查每个结果时,不会在应用程序中调用。您可能想看看设计原则,如 KISS -原则(保持简单,愚蠢)。

        4
  •  1
  •   user7396598    7 年前

    如果“检查没有发生任何其他情况”的范围是为了确保模型的状态没有改变,那么问题就是这样。

    编写一个helper函数,该函数在事件之前获取模型,在事件之后获取模型,并对它们进行比较。让它返回更改的属性,然后您可以断言,只有那些您想要更新的属性才在返回列表中。这种助手是可移植的、可维护的和可重用的

    检查模型状态是单元测试的有效应用。

        5
  •  0
  •   Bjartur Thorlacius    5 年前

    这仅在引用透明的语言(如Safe Haskell)中才可能实现。