2

我被告知不要使用实现细节。依赖项似乎是一个实现细节。但是,我也可以将其表述为一种行为。

示例:LinkList 依赖于存储引擎来存储其链接(例如 LinkStorageInterface)。构造函数需要传递一个已实现的 LinkStorageInterface 的实例来完成它的工作。我不能说'shouldUseLinkStorage'。但也许我可以说“shouldStoreLinksInStorage”。

在这种情况下“测试”什么是正确的?我应该测试它是否将链接存储在商店(行为)中,还是根本不测试?

4

2 回答 2

4

依赖项本身不是预期的行为,但对依赖项调用的操作肯定是。您应该测试您(调用者)知道的内容,并避免测试需要您深入了解 SUT 内部工作的内容。

稍微扩展您的示例,让我们假设我们的 LinkStorageInterface 具有以下定义(伪代码):

Interface LinkStorageInterface

  void WriteListToPersistentMedium(LinkList list)

End Interface

现在,由于您(调用者)正在为该接口提供具体实现,因此您可以在WriteListToPersistentMedium()调用.Save()LinkList

测试可能看起来像这样,再次使用伪代码:

void ShouldSaveLinkListToPersistentMedium()

  define da = new MockLinkListStorage()  
  define list = new LinkList(da)

  list.Save()

  Assert.Method(da.WriteListToPersistentMedium).WasCalledWith(list)

end method

您已经测试了预期的行为,而没有测试您的 SUT 或您的模拟的实现特定细节。您想要避免测试的(主要)是:

  1. 调用方法的顺序
  2. 公开一个方法或属性,以便您可以检查它
  3. 任何不直接涉及您正在测试的预期行为的内容

同样,依赖项是您作为类的消费者提供的东西,因此您希望它被使用。否则,一开始就没有这种依赖关系。

于 2009-08-11T21:40:55.207 回答
1

LinkStorageInterface 不是一个实现细节——它的名字暗示了一个引擎的接口。在这种情况下,名称shouldUseLinkStorageshouldStoreLinksInStorage更有价值。

那是我的2便士价值!

于 2009-08-11T21:29:02.327 回答