如何在 Swift 包中为 UIViewRepresentable 编写测试

问题描述

我正在尝试为我的项目创建一个 swift 包,其中包含一些共享的 UI 元素,我想为它编写一些测试

这是其中一景

    //
//  TextField.swift
//  Test
//
//  Created by Development on 05/03/2021.
//

#if !os(macOS)
import Combine
import SwiftUI
import UIKit

public struct TextFieldRepresentable: UIViewRepresentable {
    @Binding var text: String
    @Environment(\.isSecureField) var isSecureField: Bool
    @Environment(\.isFirstResponder) var isFirstResponder: Binding<Bool>?
    @Environment(\.placeholder) var placeholder: String?
    @Environment(\.keyboardType) var keyboardType: UIKeyboardType
    @Environment(\.returnKeyType) var returnKeyType: UIReturnKeyType
    @Environment(\.textContentType) var contentType: UITextContentType?
    @Environment(\.autoCapitalisation) var autoCapitalisation: Bool
    @Environment(\.autoCorrection) var autoCorrection: Bool
    @Environment(\.font) var font: Font?

    let onCommit: (() -> Bool)?
    
    public init( text: Binding<String>,onCommit: (() -> Bool)? = nil ) {
        _text = text
        self.onCommit = onCommit
    }
    
    public func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        textField.delegate = context.coordinator
        syncValues(context: context,textField: textField)
        return textField
    }

    public func updateUIView(_ uiView: UITextField,context: Context) {
        syncValues(context: context,textField: uiView)
        dispatchQueue.main.async {
            if let isFirstResponderValue = isFirstResponder?.wrappedValue {
                switch isFirstResponderValue {
                case true:
                    uiView.becomeFirstResponder()
                case false:
                    uiView.resignFirstResponder()
                }
            }
        }
    }

    private func syncValues(context _: Context,textField: UITextField) {
        textField.text = text
        textField.isSecureTextEntry = isSecureField
        textField.textContentType = contentType
        textField.keyboardType = keyboardType
        textField.placeholder = placeholder
        textField.font = UIFont.preferredFont(from: font)
        textField.autocapitalizationType = autoCapitalisation ? .sentences : .none
        textField.returnKeyType = returnKeyType
        textField.setContentCompressionResistancePriority(.defaultLow,for: .horizontal)
        textField.autocorrectionType = autoCorrection ? .yes : .no
    }

    public func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }

    public class Coordinator: NSObject,UITextFieldDelegate {
        private let parent: TextFieldRepresentable

        init(parent: TextFieldRepresentable) {
            self.parent = parent
        }

        public func textFieldShouldReturn(_: UITextField) -> Bool {
            return parent.onCommit?() ?? true
        }

        public func textFieldDidChangeSelection(_ textField: UITextField) {
            parent.$text.wrappedValue = textField.text ?? ""
        }

        public func textFieldDidBeginEditing(_: UITextField) {
            parent.isFirstResponder?.wrappedValue = true
        }
    }
}
#endif

我想测试一下,当我应用修饰符时,底层 UIView 会响应更改。有没有办法在 SPM 单元测试中加载这个视图并获取底层 UITextField 以便我可以看到修改器工作?

我尝试使用 IntrospectViewInpsector 但没有成功。

我还注意到,在 SPM 中,即使我构造了 View ma​​keUIView(context: Context) -> UITextFieldupdateUIView(_ uiView: UITextField,context: Context) 函数永远不会被调用。我在 iOS 项目单元测试中尝试了同样的事情,并且函数被正确调用。检查下面的代码

import Foundation
import XCTest
import SwiftUI

@testable import UI

final class TextFieldRepresentableTests: XCTestCase {
    

    
    var view:TextFieldRepresentable!
    var controller:UIHostingController<TextFieldRepresentable>!
    override func setUp() {
        view = TextFieldRepresentable(text: .constant("Test"))
        controller = UIHostingController(rootView: view)
        controller.loadViewIfNeeded()
        let window = UIWindow(frame: UIScreen.main.bounds)
        window.rootViewController = controller
        window.makeKeyAndVisible()
    }
    
    func test_isSecureField_IsTrue_ShouldTextFieldBeSecure() {
        view.makeUIView(context: UIViewRepresentableContext<TextFieldRepresentable>())
        
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...