我正在使用故事板,并且在视图控制器中创建了出口.在视图加载中,我已经将委托和数据源设置为self.我试图为表视图出口编写单元测试,但实际上,它返回nil,尽管它存在..

以下是视图模型代码.

class CakeListViewModel: CakeListViewModelType {
    

    weak private var delegate: CakeListViewType!
    let service:Service!
    
    private var cakes:[Cake]?
    
    var itemCount: Int {
        return cakes?.count ?? 0
    }
    
    init(delegate: CakeListViewType,
         service:Service = ServiceImpl()) {
        self.delegate = delegate
        self.service = service
    }
    
    /*
     this method connect calls rest API to get data
     */
    func fetchCakes() {
        let client = ServiceClient(baseUrl:EndPoints.baseUrl.rawValue, path:Path.cakeList.rawValue, params:"", method:"get")
        
        service.fetchData(client:client, type:Cake.self) { [weak self] (result)  in
            switch result {
            case .success(let result):
                self?.cakes = result
                DispatchQueue.main.async {
                    self?.delegate?.updateUI()
                }
            case .failure(_):
                self?.cakes = nil
                DispatchQueue.main.async {
                    self?.delegate?.showError()
                }
            }
        }
    }
}

这是我的测试代码..

class CakeViewModelTest: XCTestCase {
    
    var mockService:MockService!
    var viewModel:CakeListViewModel!


    override func setUp() {
        mockService = MockService()
        let vc = CakeListViewController()
        viewModel = CakeListViewModel(delegate:vc, service:mockService)
    }

    func testTableViewOutlet() {
        let vc =  CakeListViewController()
        XCTAssertNotNil(vc.tableView)
    }
}

以下是我的视图控制器代码.

class CakeListViewController: UIViewController {
    
    @IBOutlet var tableView: UITableView!
    
    var viewModel:CakeListViewModelType!
    weak var coordinator: Coordinator?

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        title = "?CakeItApp?"
        
        viewModel.fetchCakes()
    }
}

以下是错误的屏幕截图.

error in view model in view did load

error

推荐答案

您正在使用的视图控制器初始值设定项不使用情节提要.因此,您在情节提要中设置的任何内容(插座、约束等)都不会存在于视图控制器中.您需要替换该行:

let vc = CakeListViewController()

使用类似以下代码的代码:

if let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourViewControllerID") as? CakeListViewController {
}

"Main"替换为您的故事板的名称(如果它实际上不是"Main").

"YourViewControllerID"替换为您在情节提要中为视图控制器指定的实际ID.


解决了这个问题后,您会遇到更多问题.您的CakeListViewController有一个隐式展开的可选名称viewModel,它在viewDidLoad中被访问.因此,您必须确保在创建视图控制器后立即设置viewModel.

if let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourViewControllerID") as? CakeListViewController {
    vc.viewModel = someViewModelInstance
    // Do your tests here
}

Swift相关问答推荐

将`@Environment`值赋给`Binding`参数

如何异步返回视图?什么?

为什么这个快速代码不显示文本字段?

如何为我的项目设置生命周期选项?

如何使用 Swift 在非本地函数中切换()一个 Bool?

可以使 Swift init 仅可用于 Objective C 吗?

列表不显示信息

NavigationStack 和 TabView - 工具栏和标题不显示

如何为等待函数调用添加超时

在 macOS (Swift) 上获取 BSD 驱动器名称的最佳方法是什么?

如何在 Swift 中对单个单词进行词形还原

SwiftUI Grid 中的数组旋转

无法增加系统镜像的大小

在运行时访问 UIView 宽度

FCM 后台通知在 iOS 中不起作用

是 swift 中另一个日期的同一周、月、年的日期

使用 DispatchTime.now() + float 延迟?

Swift UITableView reloadData 在一个闭包中

为什么枚举具有计算(computed)属性但在 Swift 中没有存储属性?

通过单击表格视图中的单元格打开新的视图控制器 - Swift iOS