[英]Testing SwiftUI body views and properties
我正在研究如何對SwiftUI視圖代碼進行單元測試。
我有以下定義:
struct ContentView : View {
var body: some View {
Text("Hello World")
.font(.title)
.fontWeight(.bold)
}
}
我可以這樣測試:
func testBody() {
let cv = ContentView()
let body = cv.body
XCTAssertNotNil(body)
guard let text = body as? Text else { XCTFail(); return }
XCTAssertEqual(Text("Hello World").font(.title).fontWeight(.bold), text)
}
但是,一旦我想測試文本對齊方式,就會遇到問題:
生產代碼:
struct ContentView : View {
var body: some View {
Text("Hello World")
.font(.title)
.fontWeight(.bold)
.multilineTextAlignment(.leading)
}
}
和測試代碼:
func testBody() {
let cv = ContentView()
let body = cv.body
XCTAssertNotNil(body)
guard let text = body as? Text else { XCTFail(); return }
// COMPILER ERROR ON NEXT LINE
XCTAssertEqual(Text("Hello World").font(.title).fontWeight(.bold).multilineTextAlignment(.leading), text)
}
...然后出現以下編譯器錯誤:
Cannot convert value of type 'Text' to expected argument type '_ModifiedContent<Text, _EnvironmentKeyWritingModifier<HAlignment>>'
如何測試Text
結構的對齊方式?
.font(_:)
有兩個擴展名,即:
extension View {
/// Sets the default font for text in this view.
///
/// - Parameter font: The default font to use in this view.
/// - Returns: A view with the default font set to the value you supply.
public func font(_ font: Font?) -> Self.Modified<_EnvironmentKeyWritingModifier<Font?>>
}
和
extension Text {
/// Sets the font to use when displaying this text.
///
/// - Parameter font: The font to use when displaying this text.
/// - Returns: Text that uses the font you specify.
public func font(_ font: Font?) -> Text
}
在Text
結構上執行方法.font時, 您將使用所應用的字體返回一個新的Text
,因為它調用了font(_:)
的重載(創建具有更特定返回類型的重載方法總是可以的) 。 當您在例如Button
上調用font方法時,返回類型為:
ModifiedContent<Button<Text>, _EnvironmentKeyWritingModifier<Font?>>
好吧,這不再是普通的Button
,而是一個包裝的非常復雜的類型,因為它不像Text那樣具有自身的重載,因此它稱為“ normal”方法。
當您在Text
實例上調用multilineTextAlignment
時會發生什么?
extension View {
/// Sets the alignment of multiline text in this view.
///
/// - Parameter alignment: A value you use to align lines of text to the
/// left, right, or center.
/// - Returns: A view that aligns the lines of multiline `Text` instances
/// it contains.
public func multilineTextAlignment(_ alignment: HAlignment) -> Self.Modified<_EnvironmentKeyWritingModifier<HAlignment>>
}
Text
沒有重載,就像font方法一樣。 這意味着返回類型與新的Text
實例不同。 現在,我們陷入了一個復雜的時期。
幸運的是,該復雜類型具有content
屬性。 執行此操作時,您的測試將編譯:
XCTAssertEqual(Text("Hello World").font(.title).fontWeight(.bold).multilineTextAlignment(.leading).content, text)
注意到content
屬性:)?
運行測試時, body
變量不是您想要的那樣為Text
類型,而是具有另一個非常復雜的類型,這就是測試失敗的原因。 要通過測試,請執行以下操作:
func testBody() {
let cv = ContentView()
let body = cv.body
XCTAssertNotNil(body)
// Yuk!! Ugly cast, but don't know how to fix it since yeah, it is the type of the body...
guard let text = body as? (_ModifiedContent<Text, _EnvironmentKeyWritingModifier<HAlignment>>) else { XCTFail(); return }
// No compile error :) and a passing test!
XCTAssertEqual(Text("Hello World").font(.title).fontWeight(.bold).multilineTextAlignment(.leading).content, text.content)
}
您可以使用ViewInspector庫對SwiftUI層次結構進行單元測試:
let view = ContentView()
let string = try view.inspect().text().string()
XCTAssertEqual(string, "Hello, world!")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.