|
|
1
5
您所描述的是添加一个必须测试的全新状态,而不是空结果,现在数据库中出现了一些对象。你的测试套件怎么可能知道被测对象对一些新的随机对象的预期行为是什么?你需要编写一个新的测试。 正如你所说,这种模仿不是“行为不端”。模拟正在执行您设置的操作。规范更改的事实对模拟没有影响。在这种情况下,唯一的问题是实施更改的人忘记更新单元测试。实际上,我不太确定为什么你认为存在任何重复的担忧。 向系统添加一些新返回结果的编码器负责添加一个单元测试来处理这种情况。如果该代码也100%确定 不可能 mocking的全部目的是将测试与实际资源解耦。它不会自动让你避免在系统中引入错误。如果你的单元测试在收到null时准确地描述了行为,那太好了!但是这个测试不应该知道任何其他状态,当然也不应该以某种方式被告知外部资源将不再发送空值。
|
|
|
2
4
你没有错过什么。这是使用模拟对象进行单元测试的一个弱点。听起来你正在正确地将单元测试分解为合理大小的单元。这是一件好事;更常见的情况是,人们在“单元”测试中测试得太多。
所以总结一下:
|
|
|
3
2
|
|
|
4
2
[EDIT]基于注释:模拟只能允许实例化被测类并允许收集其他信息。尤其是,它必须 从不 影响你想要测试的结果。 [EDIT2]模拟数据库意味着您不关心DB驱动程序是否工作。你想知道的是你的代码是否能正确解释数据库返回的数据。此外,这是测试错误处理是否正常工作的唯一方法,因为您无法告诉真正的DB驱动程序“当您看到此SQL时,抛出此错误”。这只能在模拟中实现。 我同意,这需要一些时间来适应。以下是我的做法:
|
|
|
5
1
问题
当你编写代码时,你会多次使用你的方法。你会得到方法定义和使用之间的1:n关系。使用该方法的每个类都将在相应的测试中使用它的模拟。因此,该模拟也被使用了n次。
你的方法结果曾经被认为永远不会
.
随着时间的推移,你忘了什么。..模拟永远不会返回
你的 QA将失败
解决方案
为了避免这样的问题,你必须从一开始就编写更好的测试。如果你错过了测试类应该处理错误或
稍后很难添加此内容。-所以早点开始,做大量的测试。 和 缺少的相应测试不会出现在代码覆盖率中。
这不仅包括
传递错误参数
(比如
因为每个调用类都处理错误或
提示: 保持你的模型简单干净。将预期的返回值移动到测试方法。(你的模拟可以简单地将它们传递回去。)避免在模拟中测试决策。 |
|
|
6
1
您正在使用实体的模拟对象,使用JMock测试应用程序的业务层。您还可以使用DBUnit测试DAO层(应用程序和数据库之间的接口),并传递填充有一组已知值的实体对象的真实副本。因为您使用了两种不同的方法来准备测试对象,所以您的代码违反了DRY,并且随着代码的更改,您的测试可能会与现实不同步。 福尔沃说。.. Mocks Aren't Stubs 嘲笑者 方式,而“实物”路线是 执行测试的方法。 在解决这个问题时,尽可能保持干燥的一种方法是 嘲笑者 用户制造商避免重复 制造商
总是 |
|
|
7
1
单元测试不应该关心实现细节。
如果您计划稍后将此条件细化,那么您应该将NULL检查包装成返回信息异常、枚举或显式命名的bool的内容。
此外,您需要在单元测试代码中保持与生产代码相同的纪律,避免出现重复和功能嫉妒的味道。 |
|
|
8
0
如果不考虑上述内容,在初始场景中仍然有两个重要因素在起作用。您希望对单元测试代码给予与其他代码相同的关注,这意味着保持它们干燥是合理的。如果你在做TDD,这甚至会在一开始就把这个问题推到你的设计中。如果你对此不感兴趣,另一个相反的因素是YAGNI,你不想在代码中得到每一个(不)可能的场景。所以,对我来说,这将是:如果我的测试告诉我我遗漏了什么,我会仔细检查测试是否正常,然后继续进行更改。我确保在测试中不要做假设情景,因为这是一个陷阱。 |
|
|
9
0
如果我正确理解了这个问题,那么您有一个使用模型的业务对象。有一个测试测试BO和模型之间的交互(测试a),还有一个测试是测试模型和数据库之间的交互的(测试B)。测试B更改为返回一个对象,但该更改不会影响测试A,因为测试A的模型被模拟了。
|
|
|
10
-1
但是,我可以通过快速阅读来提取的意思对我来说没有什么意义,因为你想要一个不改变合同的变化来影响模拟的工作方式。 模拟使您能够专注于测试系统的特定部分。模拟部分将始终以指定的方式工作,测试可以专注于测试它应该测试的特定逻辑。因此,您不会受到无关逻辑、延迟问题、意外数据等的影响。 您可能会有单独数量的测试在另一个上下文中检查模拟功能。
|
|
|
11
-2
我认为你的问题违反了利斯科夫替代原则: 子类型必须可替换其基类型
从技术上讲,你可能看起来依赖于一个抽象,但在你所说的场景中,你并没有真正依赖于抽象,你实际上依赖于一种实现。你说“如果这个方法改变了它的行为,它的用户就会崩溃,我的测试永远不会知道”。在单元测试层面上,你是对的。但在合同层面上,以这种方式改变行为是错误的。因为通过更改方法,您显然违反了方法与其调用者之间的约定。 你为什么改变一种方法?很明显,该方法的调用者现在需要不同的行为。所以,你要做的第一件事不是改变方法本身,而是改变你的客户端所依赖的抽象或契约。他们必须首先改变并开始使用新的契约:“好吧,我的需求发生了变化,我不再希望这个方法返回,在这个特定的场景中,这个接口的实现者必须返回这个”。因此,您需要更改界面,根据需要更改界面的用户,这包括更新他们的测试,最后一件事是更改传递给客户端的实际实现。这样,您就不会遇到您所说的错误。 所以,
这看起来很可怕,但在现实生活中,对于小的变化来说,这是微不足道的,对于大的变化来说是痛苦的,事实上,这是必须的。 |
|
|
Ricky Mo · 角度测试如何模拟导入的const 2 年前 |
|
|
Robert · 如何模拟Perl的unlink函数? 2 年前 |
|
|
Ivan · 模拟没有按预期工作(Django) 2 年前 |
|
|
Erfan Sabouri · 在laravel中测试多存储 2 年前 |