我被告知不要使用实施细节。依赖关系似乎是一个实现细节。但是,我也可以将其视为一种行为。
示例:LinkList依赖于存储引擎来存储其链接(例如LinkStorageInterface)。构造函数需要传递一个已实现的LinkStorageInterface的实例来完成它的工作。 我不能说'shouldUseLinkStorage'。但也许我可以说'shouldStoreLinksInStorage'。
在这种情况下,“测试”的正确性是什么?我应该测试它在商店中存储链接(行为)还是根本不测试它?
答案 0 :(得分:4)
依赖项本身不是预期的行为,但是依赖性调用的操作肯定是。你应该测试你(调用者)所知道的东西,并避免测试那些需要你对SUT内部工作情况有深入了解的东西。
稍微扩展您的示例,让我们假设我们的LinkStorageInterface具有以下定义(伪代码):
Interface LinkStorageInterface
void WriteListToPersistentMedium(LinkList list)
End Interface
现在,由于您(调用者)正在为该接口提供具体实现,因此当您在{{1}上调用WriteListToPersistentMedium()
方法时,测试Save()
被调用是完全合理的。 }}
测试可能看起来像这样,再次使用伪代码:
LinkList
您已经测试了预期的行为,但没有测试您的SUT或模拟的实现特定细节。您希望避免测试(主要是)的是:
同样,依赖性是您作为类的使用者提供的东西,因此您希望它被使用。否则,首先要有这种依赖是没有意义的。
答案 1 :(得分:1)
LinkStorageInterface不是一个实现细节 - 它的名字暗示了一个引擎的接口。在这种情况下,名称 shouldUseLinkStorage 的价值高于 shouldStoreLinksInStorage 。
这是我的2便士价值!