如何用通用逻辑测试2种方法? [英] How to test 2 methods with common logic?

查看:32
本文介绍了如何用通用逻辑测试2种方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有 2 个公共方法:

Let's say that I have 2 public methods:

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的格式化逻辑.

Both of them depend on the formatting logic of textForData.

textForData 有(使用这种最小化实现)3 种可能的情况.如果我为我的两个公共函数测试所有可能的情况,我最终会得到 6 个测试方法,其中 3 个也将测试其他 3 个已经测试过的相同逻辑.

textForData has (with this minimized implementation) 3 possible cases. If I do test every possible case for both of my public functions, I'll end up with 6 test methods, and 3 of them would also be testing the same logic that was already tested by the other 3.

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

What's the proper way of testing this?

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

Ps.: I could write a separate test for textForData and in the tests for the public methods I assert that the textForData is called, but that seems to break the encapsulation of my class and I don't want to make the testForData public. I also wouldn't like to make a separate class just for my textForData logic, because I would end up creating too many dependencies for this current class, and that logic doesn't seem to fit anywhere else besides in this class.

推荐答案

这里有几个选项.

  1. 不要测试textForData
  2. 在使用它的公共方法的每个测试中复制行为
  3. textForData 设为公开
  4. textForData创建一个公共类
  1. Don't test textForData
  2. Duplicate the behaviour in each test of the public method that uses it
  3. Make textForData public
  4. Make a public class for textForData

第 1 点和第 2 点是不可取的.

Point 1 and 2 are undesirable.

您似乎对第 3 点感到奇怪,但这样做有好处.如果您真的很关心这样做,您将能够测试一次此行为.我不懂 Swift,但在其他语言中,这并没有看起来那么糟糕.一般建议是针对和接口编码,而不是实现.所以这个类的公共接口会有didSelectdidDismiss.您的生产代码将根据此接口表示,这意味着即使 textForData 是类上的公共方法,您也无法直接访问它.

You seem oddly against point 3, but there are benefits to doing this. You will be able to test this behaviour once, given you really care about doing so. I don't know Swift, but in other languages this isn't as bad as it seems. The general advice is to code against and interface, rather than an implementation. So the public interface of this class would have didSelect and didDismiss. Your production code would be expressed in terms of this interface, meaning even though textForData is a public method on the class you cannot access it directly.

这里的好消息是您的测试可以针对一个实现编写(事实上,他们必须这样做),因此在这里您可以访问所有三种方法.因此,您可以尽情测试.

The good news here is that your tests can be written against an implementation (in fact, they have to) so here you'll have access to all three methods. So you can test to your hearts content.

第 4 点与第 3 点类似,但存储为单独的类.鉴于您可能会争辩说我们违反了第 3 点中的单一职责原则,我会选择这个.为了隐藏这一点,如果您声明此代码仅在此示例中使用,我将首先创建一个嵌套类.同样,您的测试将可以使用与上述相同的想法来访问它.

Point 4 is similar to point 3, but stored as a separate class. I'd opt for this given that you could argue we have broken the Single Responsibility Principle in point 3. To hide this I'd make a nested class to begin with given you state this code is only used within this one example. Again, your tests will have access to this using the same ideas as above.

您的代码正朝着拥抱组合的方向发展,因此您应该享受诸如小类、精心分解的代码等优点.

You're code is moving towards embracing composition, therefore you should embrace the benefits such as small classes, well factored code and more.

这篇关于如何用通用逻辑测试2种方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆