如何对@ViewBuilder 函数进行单元测试?
How to unit test an @ViewBuilder function?
示例函数:
@ViewBuilder func returnView() -> some View {
if thisIsTrue == true {
SomeView()
} else {
AnotherView()
}
}
我试过这样测试:
let testView = sut.returnView()
XCTAssert(testView is SomeView)
当只有一种可能的视图类型时通过,但一旦有选择就会失败。
关于如何对这个函数的输出进行单元测试有什么建议吗?
不透明 return 类型 some View
意味着此函数始终 return 在函数的所有路径上恰好是一种类型,并且该类型符合 View
,所以虽然看起来您正在 return 处理两种不同的事物,但 ViewBuilder 实际上将其折叠为一种类型,该类型相对于真正的 return 类型是通用的。如果你想知道真正的不透明类型是什么,你可以让编译器告诉你。例如这里是一个游乐场。请注意,此解决方案很脆弱,因为更改函数的实现很可能会更改 return 类型。
import SwiftUI
struct SomeView: View {
var body: some View { EmptyView() }
}
struct AnotherView: View {
var body: some View { Color.red}
}
@ViewBuilder func returnView() -> some View {
if true {
SomeView()
} else {
AnotherView()
}
}
let a = returnView()
print(type(of: a))
输出:
_ConditionalContent<SomeView, AnotherView>
我采用的解决方案是根本不对函数的输出进行单元测试。
我在视图模型中创建了一个枚举,其中包含映射到不同视图的案例,然后使用此类型的计算 属性 将业务逻辑与视图逻辑分开。
enum ViewType {
case someView
case anotherView
}
var viewType: ViewType {
if thisIsTrue {
return .someView
} else {
return .anotherView
}
}
我可以在我的单元测试中实例化和测试它。
然后在视图本身中,我创建了一个@ViewBuilder 变量并使用 switch 语句将其映射到视图模型 viewType:
@ViewBuilder var view: some View {
switch viewModel.viewType {
case .someView:
SomeView()
case .anotherView:
AnotherView()
}
}
我希望这对其他人有帮助。
示例函数:
@ViewBuilder func returnView() -> some View {
if thisIsTrue == true {
SomeView()
} else {
AnotherView()
}
}
我试过这样测试:
let testView = sut.returnView()
XCTAssert(testView is SomeView)
当只有一种可能的视图类型时通过,但一旦有选择就会失败。
关于如何对这个函数的输出进行单元测试有什么建议吗?
不透明 return 类型 some View
意味着此函数始终 return 在函数的所有路径上恰好是一种类型,并且该类型符合 View
,所以虽然看起来您正在 return 处理两种不同的事物,但 ViewBuilder 实际上将其折叠为一种类型,该类型相对于真正的 return 类型是通用的。如果你想知道真正的不透明类型是什么,你可以让编译器告诉你。例如这里是一个游乐场。请注意,此解决方案很脆弱,因为更改函数的实现很可能会更改 return 类型。
import SwiftUI
struct SomeView: View {
var body: some View { EmptyView() }
}
struct AnotherView: View {
var body: some View { Color.red}
}
@ViewBuilder func returnView() -> some View {
if true {
SomeView()
} else {
AnotherView()
}
}
let a = returnView()
print(type(of: a))
输出:
_ConditionalContent<SomeView, AnotherView>
我采用的解决方案是根本不对函数的输出进行单元测试。
我在视图模型中创建了一个枚举,其中包含映射到不同视图的案例,然后使用此类型的计算 属性 将业务逻辑与视图逻辑分开。
enum ViewType {
case someView
case anotherView
}
var viewType: ViewType {
if thisIsTrue {
return .someView
} else {
return .anotherView
}
}
我可以在我的单元测试中实例化和测试它。
然后在视图本身中,我创建了一个@ViewBuilder 变量并使用 switch 语句将其映射到视图模型 viewType:
@ViewBuilder var view: some View {
switch viewModel.viewType {
case .someView:
SomeView()
case .anotherView:
AnotherView()
}
}
我希望这对其他人有帮助。