测试在私有变量中保留其状态的类

2024-04-28

我正在为我的班级编写单元测试。此类在某些情况下保留其状态private变量(我不想公开暴露)。所以场景是:

  • 如果我调用一个方法,第一次它会保持该状态private属性并调用委托方法并返回一些结果。
  • 当我第二次调用相同的方法时,输出将根据之前的输入而有所不同。

我想在我的测试中涵盖所有情况。

  • 一种简单的方法是将我的私有属性更改为公共属性,以便我可以在单元测试中模拟以前的输入。
  • 另一种方法是在同一个测试中使用不同的输入调用同一方法两次。第一次调用将保留状态,下一次调用将是实际测试。

但这两种方式对我来说似乎都很尴尬,而且我不确定哪一种是最好的。 为此类编写单元测试的最佳方法是什么?

protocol ZoneUpdateDetectorOutput: class {
    func updateZoneState(_ state: ZoneState)
}

class ZoneUpdateDetector {
    var zoneChangeTimer: TimerProtocol?
    weak var delegate: ZoneUpdateDetectorOutput?

    private var previousZoneState: ZoneState?
    private var expectedZoneState: ZoneState?

    private func updateZoneState() {
        // If `expectedZoneState` is not equal to `previousZoneState` then `delegate` will be called
        // Otherwise it will just skip
        if expectedZoneState != previousZoneState {
            delegate?.updateZoneState(expectedZoneState!)
            previousZoneState = expectedZoneState
        }
    }

    private func runNotifyZoneStateTimer() {
        guard zoneChangeTimer?.isValid() == false else {
            return
        }
        zoneChangeTimer?.start(timeInterval: 5,
                               onFire: { [weak self] in
                                guard let strongSelf = self else {
                                    return
                                }
                                // On timer fire, it will try to update the state
                                strongSelf.updateZoneState()
        })
    }

    // When zone changes, this method is invoked
    // I basically want to test this method
    func zoneStateChanged(_ state: ZoneState) {
        expectedZoneState = state
        if state != .inZone {
            runNotifyZoneStateTimer()
        } else {
            zoneChangeTimer?.stop()
        }
    }
}

你永远不应该测试内部状态;您应该只测试外部(公开)可见的行为。这样,您就可以更改类的实现细节,而不会破坏任何契约,因此也不会破坏任何测试。

所以第二个选项是首选。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

测试在私有变量中保留其状态的类 的相关文章

随机推荐