【问题标题】:Unit testing an @ObservableObject in Swift Test Driven Development在 Swift 测试驱动开发中对 @ObservableObject 进行单元测试
【发布时间】:2020-06-02 14:40:21
【问题描述】:

我正在尝试学习如何使用带有 TDD 的 MVVM 架构来解决一些无法在 SwiftUI 中对视图进行单元测试的问题。

我有一个带日期的 Alarm 结构:

import Foundation

struct Alarm {
    var time: Date
}

我有一个基本的

class AlarmPickerViewModel: ObservableObject {
    @Published var alarm: Alarm

    init(alarm: Alarm) {
        self.alarm = alarm
    }

}

如果AlarmPickerViewModel 不是ObservableObject 的子类并且警报属性不是@Published,我正在努力研究如何编写一个失败的单元测试。

我查看了this question on the site,但它似乎对我没有帮助。

请指点一下我哪里出错了?

【问题讨论】:

  • “无法在 SwiftUI 中对视图进行单元测试的一些问题。”那不是真的。在 SwiftUI 中,您可以对视图进行单元测试 - 或至少在视图中测试业务逻辑,因为您可以像使用任何其他实体一样使用依赖注入。 SwiftUI 解决了 UIKit UIViewsUIViewControllers 不能依赖注入的问题。唯一不能进行单元测试的部分是 UI 的实际外观。
  • 谢谢,知道这真的很有用。

标签: swift mvvm tdd observableobject


【解决方案1】:

如果alarm 不是@Published,您可以创建一个甚至不会编译的测试,只需创建对该属性的订阅,因为您只有在它是@Published 时才能订阅它。

ObservableObject 一致性将objectWillChange Publisher 添加到您的对象中,因此要对其进行测试,您只需订阅该Publisher。如果 AlarmPickerViewModel 不是 ObservableObject,则测试甚至无法编译。

func testAlarmPickerViewModel() {
    let alarmPickerViewModel = AlarmPickerViewModel(alarm: Alarm(time: .distantFuture))

    alarmPickerViewModel.$alarm.sink(receiveValue: { print("ViewModel.alarm updated, new value: \($0)") })

    alarmPickerViewModel.objectWillChange.sink(receiveValue: { print("ViewModel updated: \($0)")})
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 2011-07-29
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多