BDD/TDD:依赖可以是一种行为吗?
我被告知不要使用实施细节。 依赖关系看起来像是一个实现细节。 但我也可以将其表述为一种行为。
示例:LinkList 依赖于存储引擎来存储其链接(例如 LinkStorageInterface)。 构造函数需要传递一个已实现的 LinkStorageInterface 的实例才能完成其工作。 我不能说“shouldUseLinkStorage”。 但也许我可以说“shouldStoreLinksInStorage”。
在这种情况下,什么是正确的“测试”? 我应该测试它是否在商店中存储链接(行为)还是根本不测试它?
I've been told not to use implementation details. A dependency seems like an implementation detail. However I could phrase it also as a behavior.
Example: A LinkList depends on a storage engine to store its links (eg LinkStorageInterface). The constructor needs to be passed an instance of an implemented LinkStorageInterface to do its job.
I can't say 'shouldUseLinkStorage'. But maybe I can say 'shouldStoreLinksInStorage'.
What is correct to 'test' in this case? Should I test that it stores links in a store (behavior) or don't test this at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
LinkStorageInterface 不是一个实现细节——它的名字暗示了一个引擎的接口。 在这种情况下,名称 shouldUseLinkStorage 比 shouldStoreLinksInStorage 更有价值。
这就是我的2便士的价值!
LinkStorageInterface is not an implementation detail - its name suggests an interface to to an engine. In which case the name shouldUseLinkStorage has more value than shouldStoreLinksInStorage.
That's my 2 pennies worth!
依赖关系本身不是预期的行为,但对依赖关系调用的操作肯定是预期的行为。 您应该测试您(调用者)了解的内容,并避免测试需要您深入了解 SUT 内部工作原理的内容。
稍微扩展一下您的示例,让我们想象一下我们的 LinkStorageInterface 具有以下定义(伪代码):
现在,由于您(调用者)正在提供该接口的具体实现,因此您测试
WriteListToPercientMedium 是完全合理的当您在
就会被调用。LinkList
上调用Save()
方法时,()测试可能看起来像这样,再次使用伪代码:
您已经测试了预期的行为,而没有测试 SUT 或模拟的实现特定细节。 您想要避免的测试(大多数)是这样的:
再次强调,依赖关系是一种东西您作为该类的使用者所提供的,因此您希望它被使用。 否则,一开始就有这种依赖是没有意义的。
The dependency itself is not an expected behavior, but the actions called on the dependency most certainly are. You should test the stuff you (the caller) know about, and avoid testing the stuff that requires you to have intimate knowledge of the inner workings of the SUT.
Expanding your example a little, lets imagine that our LinkStorageInterface has the following definition (Pseudo-Code):
Now, since you (the caller) are providing the concrete implementation for that interface it is perfectly reasonable for you to test that
WriteListToPersistentMedium()
gets called when you invoke theSave()
method on yourLinkList
.A test might look like this, again using pseudo-code:
You have tested expected behavior without testing implementation specific details of either your SUT, or your mock. What you want to avoid testing (mostly) are things like:
Again, a dependency is something that you as the consumer of the class are providing, so you expect it to be used. Otherwise there is no point in having that dependency in the first place.