Unit testing 如何对业务规则进行单元测试?

Unit testing 如何对业务规则进行单元测试?,unit-testing,business-rules,Unit Testing,Business Rules,我需要一个单元测试来确保我正确地累积了假期时间。但是休假时间是根据业务规则累积的,如果规则改变,那么单元测试就会中断 这可以接受吗?我是否应该通过一个方法公开规则,然后从代码和测试中调用该方法,以确保单元测试不那么脆弱 我的问题是:什么是单元测试可能会更改的业务规则的正确方法?我有类似的设置-但是我的业务规则是编译的,但是有可配置的选项(您的可能不同)。当业务规则改变了它的核心操作方式时,我的单元测试就会中断。这实际上是意料之中的——而且很好!这意味着我可以隔离整个系统中的任何意外波动,并更新测

我需要一个单元测试来确保我正确地累积了假期时间。但是休假时间是根据业务规则累积的,如果规则改变,那么单元测试就会中断

这可以接受吗?我是否应该通过一个方法公开规则,然后从代码和测试中调用该方法,以确保单元测试不那么脆弱


我的问题是:什么是单元测试可能会更改的业务规则的正确方法?

我有类似的设置-但是我的业务规则是编译的,但是有可配置的选项(您的可能不同)。当业务规则改变了它的核心操作方式时,我的单元测试就会中断。这实际上是意料之中的——而且很好!这意味着我可以隔离整个系统中的任何意外波动,并更新测试以匹配更改


如果您的规则是外部的(某种脚本语言或数据库存储过程),那么您需要将它们包装在集成测试中,并连接集成测试以自动执行。虽然不再是单元测试,但集成测试也相当重要,它将以与单元测试相同的方式帮助您防止由于业务规则更改而产生意外的涟漪。

如果规则更改,测试失败听起来是正确的-这是意料之中的

如果您在测试本身中使用数据固定装置而不是硬编码的值,那么将来可以更容易地维护测试。例如,如果您的方法应该返回foo,那么您可以在fixture中使用它。当您更改业务逻辑时,您只需更改fixture,就不必进行单元测试了


当然,这在很大程度上取决于您正在测试的逻辑类型,可能并不总是适用的。

您的测试应该确保代码正确地遵守业务规则。因此,我不会编写围绕业务规则或依赖业务规则代码本身的测试。相反,当业务规则更改时,我会首先更改测试以反映新的业务规则,然后当我的代码不再通过测试时,去修复代码以使其通过测试

您不希望发生的是编写测试,这样当您更改应用相同业务规则的方式时,您的测试就会中断。这说起来容易做起来难,但实际上,您要测试的是实现规则所需的最低要求,而不必过于狭隘地说明代码是如何实现的。但是,如果规则的结果不同,那么您应该首先更改测试,然后更改代码以匹配测试


您也不希望测试与特定数据耦合。比如说,在进行税收计算时,您的测试不应该假设被测试的类使用5%作为税收。相反,您应该编写测试,以便它提供税收百分比,然后检查计算是否正确。您可能需要测试一系列值,以确保捕获超出范围的值。这样做的一个结果是,您将拥有更好的设计,因为这将帮助您避免硬编码值,并使生产代码更灵活地适应数据的更改。

听起来您有业务规则,然后您就有了这些业务规则的客户机。如果这两者可以独立变化,那么明智的做法是相应地设计API

如前所述,您的问题似乎可以通过适当使用策略模式来解决。该策略代表您的业务规则,因此您可以在纯上下文中对这些规则进行单元测试,而无需担心客户机

当业务规则更改时,简单地保留旧策略(以防以后再次需要)并编写(和单元测试)一个代表新业务规则的全新策略可能更有意义

当您完全使用新策略时,您可以在客户机中替换该策略

当对客户机进行单元测试时,您应该针对双重测试策略(如模拟或存根)进行测试,以验证客户机是否正确地与该策略交互,而不依赖于任何特定的策略实现


通过这种方式,您可以清晰地分离关注点,并保持单元测试的可维护性。你也遵守开/关原则。

我认为这是一个不正确的问题 业务规则和单元测试处于不同的抽象级别。 业务规则处于最高抽象级别(业务建模),但单元测试用于测试处于最低抽象级别的代码单元,因此您不能使用单元测试来验证或验证业务规则。
此外,分析和设计后的业务规则可能会影响多个代码单元,因此您同样不能使用单元测试来验证业务规则。
我认为您可以使用测试用例或BDD场景来验证和验证业务规则。

当您更改规则时,您会更改预期结果。这意味着过去通过的一些正面单元测试现在失败了,而过去通过的一些负面测试(通过检测错误)现在可能失败(尽管这通常不太常见)。单元测试只能验证当前规则-它们不能在规则更改之前验证对规则的所有更改。当规则更改时,单元测试可能也必须更改。这是完全错误的,通过模拟应用业务规则的对象下的层,您可以将业务层完全隔离为单个单元,因此对其进行单元测试。分析和设计后的业务规则可能会影响多个代码单元,您想模拟其中的哪一个?如何实现业务规则的纯实现?当然,但重点是什么?要维护一个大型测试还是单单元测试?