1
13
是的,你是对的。一个类,它是
此外,如果它与程序的其他部分(共同)依赖,那么即使在看起来不相关的、远离代码的部分中,它的任何更改也可能会破坏某些东西。 TDD不仅仅是一种测试代码的方法,它也是一种不同的设计方法。有效地 使用 -从一开始就考虑使用你自己的类和接口,可能会导致与传统的“代码和祈祷”方式截然不同的设计。一个具体的结果是,通常您的大多数关键代码都与系统的边界隔离开来,即有包装器/适配器在适当的位置来隐藏,例如,混凝土数据库不在系统的其余部分,“有趣的”(即,可测试的)代码不在这些包装器中-这些都尽可能简单-但在系统的其余部分相对长度单位。 现在,如果您有一堆没有单元测试的代码,并且想要覆盖它,那么您就有一个挑战。模拟框架可能会有很大的帮助,但是为这样的代码编写单元测试仍然是个麻烦。处理此类问题的良好技术来源(通常称为 遗留代码 是 Working Effectively with Legacy Code 迈克尔·费瑟。 |
2
11
是的,松耦合的设计可能更好,但最终需要数据来进行测试。 您应该研究模拟框架来模拟数据库和这个类所依赖的其他类,以便更好地控制测试。 |
3
11
我发现 dependency injection 是最有助于使我的代码可测试的设计模式(而且,通常也可以重用,并适应不同于我为其设计的原始环境的上下文)。我的JAVA使用同事崇拜 Guice ;我主要用python编程,所以我通常“手动”进行依赖项注入,因为duck类型使它变得容易;但是对于静态或动态语言来说,它是正确的基本dp(不要让我开始使用“monkey patching”……让我们说它不是我最喜欢的;-)。 一旦您的类准备好“从外部”接受它的依赖项,而不是对它们进行硬编码,您当然可以使用依赖项的假版本或模拟版本,以使测试更容易和更快地运行——但这也会打开其他可能性。例如,如果当前设计的类的状态复杂且难以设置,请考虑 State design pattern :您可以重构设计,使状态存在于单独的依赖项中(您可以根据需要设置和注入该依赖项),并且类本身主要负责行为(更新状态)。 当然,通过这样的重构,您将引入越来越多的接口(抽象类,如果您使用C++)——但这完全正确:这是一个很好的原则,“编程到接口,而不是实现”。 因此,为了直接解决您的问题,您是对的:测试的困难绝对是设计上相当于极端编程所称的“代码味道”。不过,从好的方面来说,有一条非常清晰的路径可以将这个问题重构掉——您不必从一个完美的设计开始(幸运的是!-,但可以随你的移动而增强。我推荐这本书 Refactoring to Patterns 作为这一目标的良好指导。 |
4
6
对我来说,代码应该是 为可测试性而设计 . 另一方面,我认为不可测试或难以测试的代码设计得很糟糕(不管它有多漂亮)。 在您的案例中,也许您可以模拟外部依赖关系以实际运行 单元测试 (孤立地) |
5
2
我要换个方法:代码不是为 可测试性 但这并不意味着 设计不当 . 设计是竞争的产物 ** 其中 可测试性 只是其中之一。每个编码决策都会增加 *伊迪斯 同时减少其他。例如,设计 可测试性 一般危害其 简单性/可读性/可理解性 (因为它增加了复杂性)。一 好的 设计最重要 ** 你的处境。 你的代码不是 坏的 它只是最大化另一个 ** 以外 可测试性 . -) 更新:在我被指控为 *可测性 并不重要 当然,诀窍是设计和编码以最大限度地提高产品质量 ** 尤其是重要的。哪些是重要的取决于你的情况。以我在这种情况下的经验,为 可测试性 更重要的是 ** . |
6
1
理想情况下,大多数类都是可单元测试的,但是你永远不会达到100%,因为你必须至少有一个位专门用于将其他类绑定到一个整体程序中。(最好是在一个地方,那是明显和琐碎的正确,但不是所有的代码都是那么令人愉快的工作。) |
7
1
虽然没有一种方法可以确定类是否“设计良好”,但至少您提到的第一件事通常是设计有问题的迹象。 您测试的类不应该依赖于数据库,而应该依赖于一个对象,该对象的唯一职责是获取数据,可能使用类似于存储库或DAO的模式。 至于第二个原因,它不一定突出显示类的不良设计;它可能是测试设计(没有fixture父类型或帮助器,您可以在其中设置几个测试中使用的依赖项)和/或总体架构(即不使用工厂或控制反转来注入相应的数据)的问题。突发事件) 另外,您可能不应该为依赖项使用“真实”对象,但是测试会加倍。这有助于确保您正在测试那个类的行为,而不是它的依赖项的行为。我建议您研究模拟框架。 |
8
0
我 可以 有一个理想的解决方案供你考虑…私人访问器 最近,我担任了一个角色,我们大量使用它们来避免您所描述的情况——依赖主数据存储中维护的人工数据。 虽然这不是最简单的实现技术,但是这样做之后,您将能够轻松地在被测试的方法中定义私有成员,以满足您认为它们应该具备的任何条件,并直接从单元测试代码(因此不从数据库加载)中定义私有成员。此外,您还可以在不违反类保护级别的情况下完成目标。 然后,它是基本的断言和验证,用于正常情况下的所需条件。 |
mg610 · 如何开始C++单元测试 2 年前 |
Phil Gunning · 使用嵌套函数更改进行模拟测试 2 年前 |
shilin agre · 在Python中测试修饰函数 2 年前 |
SlipScout · Unittest只传递单个值,而不是获取多个值 2 年前 |
Alex · 从实际对象的实例返回默认模拟结果 2 年前 |