如何使用通用逻辑测试2种方法?

时间:2015-03-30 19:35:28

标签: ios unit-testing swift tdd

假设我有两种公共方法:

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种可能的情况。 如果我确实测试了我的两个公共函数的每个可能的情况,我将最终得到6个测试方法,其中3个也将测试已经由其他3个测试过的相同逻辑。

测试这个的正确方法是什么?

Ps。:我可以为textForData编写一个单独的测试,在公共方法的测试中,我断言调用了textForData,但这似乎打破了我的班级和我的封装不希望公开testForData。 我也不想为我的textForData逻辑创建一个单独的类,因为我最终会为这个当前类创建太多的依赖项,并且该逻辑似乎不适合此类中的其他任何地方

2 个答案:

答案 0 :(得分:1)

我认为数据格式化是一项自己的责任。所以你应该将它提取到自己的类中。

这门课可以单独进行单元测试。

使用此类的其他类应该通过直接使用接口而不是类来解耦。应注入依赖性(例如在建筑商中)。您可以编写一个默认构造函数来创建默认类,以简化生产代码中的内容(不良的依赖注入)。

然后你可以模拟格式化程序并单独测试其他类,验证是否正确调用了textForData方法。

答案 1 :(得分:1)

你有几个选择。

  1. 不要测试textForData
  2. 在使用它的公共方法的每个测试中复制行为
  3. textForData公开
  4. textForData
  5. 制作公开课程

    第1点和第2点是不合需要的。

    你似乎对第3点很奇怪,但这样做有好处。鉴于您真正关心这一行为,您将能够测试一次此行为。我不知道斯威夫特,但在其他语言中,这并不像看起来那么糟糕。一般的建议是编码和接口,而不是实现。因此,此类的公共接口将具有didSelectdidDismiss。您的生产代码将以此界面表示,这意味着即使textForData是该类的公共方法,您也无法直接访问它。

    这里的好消息是你的测试可以针对一个实现来编写(事实上,他们必须这样做)所以在这里你可以访问所有这三种方法。所以你可以测试你的内心。

    第4点类似于第3点,但存储为单独的类。鉴于你可以说我们在第3点中已经违反了单一责任原则,我选择了这一点。为了隐藏这个,我建立一个嵌套类,因为你声明这个代码只在这个中使用例。同样,您的测试可以使用与上述相同的想法访问它。

    你的代码正朝着拥抱作品的方向发展,因此你应该接受诸如小班,代码很好的代码等好处。