Swift单元测试中如何使用@Observable宏及展开assertMacroExpansion
如何用assertMacroExpansion展开@Observable宏
核心解决步骤
- 导入正确模块:除
Observation外,必须显式导入ObservationMacros,同时确保测试目标能访问该宏模块。 - 传入正确宏类型:
@Observable对应的宏实现是ObservableMacro.self,而非Observable.self,这是之前尝试失效的关键原因。 - 配置测试目标宏支持:在
Package.swift中为测试目标添加ObservationMacros依赖,并启用测试宏开关。
完整测试代码示例
import XCTest import Observation import ObservationMacros import SwiftSyntaxMacrosTestSupport final class ObservableMacroTests: XCTestCase { func testObservableMacroExpansion() { let input = """ @Observable class TestModel { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } } """ let expectedExpansion = """ class TestModel: Observable { var name: String { didSet { objectWillChange.send() } } var age: Int { didSet { objectWillChange.send() } } init(name: String, age: Int) { self.name = name self.age = age } } """ assertMacroExpansion( input, expandedSource: expectedExpansion, macros: [ "Observable": ObservableMacro.self ] ) } }
Package.swift配置要点
确保测试目标的依赖与编译设置正确:
let package = Package( name: "YourPackage", dependencies: [ .package(url: "https://github.com/apple/swift-observation.git", from: "1.0.0"), ], targets: [ .target( name: "YourTarget", dependencies: [ .product(name: "Observation", package: "swift-observation"), ] ), .testTarget( name: "YourTargetTests", dependencies: [ "YourTarget", .product(name: "Observation", package: "swift-observation"), .product(name: "ObservationMacros", package: "swift-observation"), .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), ], swiftSettings: [ .enableUpcomingFeature("EnableTestingMacros"), ] ), ] )
额外注意事项
- 确保
swift-observation版本与Xcode/Swift版本兼容,避免版本不匹配导致宏无法识别。 - 测试中的预期展开内容要与宏实际生成的代码完全一致,包括空格、换行和
objectWillChange调用逻辑,否则断言会失败。
内容的提问来源于stack exchange,提问作者rayaantaneja
相关产品推荐
相关产品推荐

