You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ChildView快照测试中创建并注入DismissAction实例

解决ChildView快照测试中DismissAction无法初始化的问题

DismissAction是SwiftUI通过环境提供的类型,没有公开的直接初始化器,所以不能像你尝试的那样直接创建实例。下面提供几种可行的解决方案:

方案一:注入空实现的DismissAction

虽然DismissAction没有公开的无参构造器,但可以通过闭包初始化一个空实现的实例——快照测试只关心UI渲染,不需要实际执行dismiss逻辑,这个方法完全满足需求:

class ChildViewSnapshotTests: XCTestCase {
    func testView() {
        let mockDismiss = DismissAction {}
        let view = ChildView(parentDismiss: mockDismiss)
        
        assertSnapshot(view: view)
    }    
}

方案二:用容器提供dismiss环境

把ChildView嵌入到NavigationStack(iOS 16+)或NavigationView(iOS 15及以下)中,容器会自动在环境中注入DismissAction,这样就能正常初始化ChildView:

class ChildViewSnapshotTests: XCTestCase {
    func testView() {
        let view = NavigationStack {
            ChildView(parentDismiss: .init {})
        }
        
        assertSnapshot(view: view)
    }    
}

方案三:解耦依赖(推荐)

修改ChildView,将DismissAction类型的参数替换为普通闭包() -> Void,既降低了ChildView对SwiftUI环境类型的依赖,测试也会更简洁:

修改ChildView.swift

struct ChildView: View {
    let onDismiss: () -> Void

    var body: some View {
        Button {
            onDismiss()
        } label: {
            Text("Close")
        }
    }
}

修改ContentView.swift

struct ContentView: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationView {
            ZStack {
                ChildView(onDismiss: dismiss)
                Button {
                    dismiss()
                } label: {
                    Text("close")
                }
            }
        }
    }
}

测试代码

class ChildViewSnapshotTests: XCTestCase {
    func testView() {
        let view = ChildView(onDismiss: {})
        assertSnapshot(view: view)
    }    
}

内容的提问来源于stack exchange,提问作者Ronnie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:05:23