假设我有 2 个公共(public)方法:
func didSelect(data: Data) {
// do something
self.view.showText(textForData(data))
}
func didDismiss(data: Data) {
if data.isSomething {
self.view.showText(textForData(data))
}
...
}
private func textForData(data: Data): String {
var text: String
if data.distance == nil {
text = "..."
} else if data.distance < 1000 {
text = "\(data.distance) m"
} else {
text = "\(data.distance / 1000) km"
}
return text
}
两者都依赖于textForData
的格式化逻辑。
textForData
有(通过这个最小化的实现)3 种可能的情况。
如果我为我的两个公共(public)函数测试所有可能的情况,我最终会得到 6 种测试方法,其中 3 种也将测试其他 3 种已经测试过的相同逻辑。
测试这个的正确方法是什么?
Ps.: 我可以为 textForData
编写一个单独的测试,在公共(public)方法的测试中我断言 textForData
被调用,但这似乎打破了封装我的类,我不想公开 testForData
。
我也不想只为我的 textForData
逻辑创建一个单独的类,因为我最终会为当前类创建太多依赖项,而且该逻辑似乎不适合除此之外的任何其他地方在这个类中。
最佳答案
这里有几个选项。
- 不要测试
textForData
- 在使用它的公共(public)方法的每个测试中复制行为
- 公开
textForData
- 为
textForData
创建一个公共(public)类
第 1 点和第 2 点是不可取的。
您似乎很奇怪地反对第 3 点,但这样做有好处。如果您真的很关心这样做,您将能够测试一次这种行为。我不了解 Swift,但在其他语言中,这并不像看起来那么糟糕。一般建议是针对和接口(interface)进行编码,而不是实现。所以这个类的公共(public)接口(interface)将有 didSelect
和 didDismiss
。您的生产代码将根据此接口(interface)表示,这意味着即使 textForData
是类中的公共(public)方法,您也无法直接访问它。
这里的好消息是您的测试可以针对实现编写(事实上,它们必须这样做),因此在这里您可以访问所有三种方法。所以您可以尽情测试。
第 4 点与第 3 点类似,但作为单独的类存储。我会选择这个,因为您可能会争辩说我们在第 3 点中违反了单一职责原则。为了隐藏这一点,我会首先创建一个嵌套类,前提是您声明此代码仅在这个示例中使用。同样,您的测试将使用与上述相同的想法访问它。
您的代码正朝着拥抱组合的方向发展,因此您应该拥抱诸如小类、分解良好的代码等优势。
关于ios - 如何测试具有共同逻辑的 2 种方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29354729/