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

如何为给定Swift代码编写测试用例,代码不可测时该如何改造?

Swift代码测试适配及用例编写方案

一、现有代码适配测试需要做的修改

原有代码的核心问题是SomeViewModel硬依赖MyFileManager单例,无法替换实现做Mock测试,需要做以下调整:

  • 提取协议抽象MyFileManager的能力,定义文件服务协议,声明需要用到的两个接口
  • 为SomeViewModel增加依赖注入入口,将文件管理实例作为构造参数,默认值保留原单例,不影响原有业务逻辑
  • 可选优化:将硬编码的缓存路径提取为可配置常量,方便测试时校验路径正确性

修改后的业务代码如下:

// 新增协议抽象
protocol FileStorageService {
    func isStored(atPath path: String) -> Bool
    func readData(atPath path: String) -> Data?
}

// 让原有MyFileManager实现协议
extension MyFileManager: FileStorageService {}

class SomeViewModel {
    // 把硬编码路径提取为常量
    private let cachePath = "xxxxx"
    // 注入依赖的文件服务
    private let fileStorage: FileStorageService
    
    // 构造方法默认用原有单例,业务侧代码无需修改
    init(fileStorage: FileStorageService = MyFileManager.shared) {
        self.fileStorage = fileStorage
    }

    func getCachedData() -> Data? {
        if fileStorage.isStored(atPath: cachePath) {
            return fileStorage.readData(atPath: cachePath)
        } else {
            return nil
        }
    }
}

二、逻辑覆盖测试用例编写

首先实现Mock版本的文件服务,用来模拟不同的返回场景,同时可以校验调用参数是否正确:

class MockFileStorage: FileStorageService {
    // 模拟文件是否存在的返回值
    var isFileExists: Bool = false
    // 模拟读取到的文件数据
    var mockData: Data?
    // 记录传入的路径,用于校验是否正确
    private(set) var receivedPath: String?
    
    func isStored(atPath path: String) -> Bool {
        receivedPath = path
        return isFileExists
    }
    
    func readData(atPath path: String) -> Data? {
        receivedPath = path
        return mockData
    }
}

然后编写测试用例,覆盖所有逻辑分支:

class TestSomeViewModel: XCTestCase {
    func testGetCachedData() {
        // 测试用例1:校验缓存路径合法性
        let mockStorage = MockFileStorage()
        let viewModel = SomeViewModel(fileStorage: mockStorage)
        _ = viewModel.getCachedData()
        XCTAssertEqual(mockStorage.receivedPath, "xxxxx")
        
        // 测试用例2:文件不存在分支,返回nil
        mockStorage.isFileExists = false
        let resultWhenNoFile = viewModel.getCachedData()
        XCTAssertNil(resultWhenNoFile)
        
        // 测试用例3:文件存在分支,返回对应模拟数据
        let testData = "test cache content".data(using: .utf8)
        mockStorage.isFileExists = true
        mockStorage.mockData = testData
        let resultWhenHasFile = viewModel.getCachedData()
        XCTAssertEqual(resultWhenHasFile, testData)
    }
}

三个测试点分别覆盖了路径合法性校验、文件不存在分支、文件存在分支,实现完整逻辑覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:09:03