首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使NSFileCoordinator在单元测试环境中生成错误?

如何使NSFileCoordinator在单元测试环境中生成错误?
EN

Stack Overflow用户
提问于 2022-07-26 10:20:07
回答 1查看 84关注 0票数 0

我为NSFileCoordinator API编写了一个异步接口。

代码语言:javascript
复制
struct FileCoordinator {
    private init() {}
    static let shared = FileCoordinator()
    
    func coordinateWriting(of data: Data, to url: URL) async throws {
        try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation<Void, Error>) in
            var error: NSError?
            
            func handleWriting(newURL: URL) {
                do {
                    try data.write(to: newURL, options: .atomic)
                    continuation.resume()
                } catch {
                    continuation.resume(throwing: error)
                    // This is the line that I have been able to test by making this method write to dev null.
                }
            }
            
            NSFileCoordinator().coordinate(writingItemAt: url, options: .forReplacing, error: &error, byAccessor: handleWriting)
            
            // Developer documentation: If a file presenter encounters an error while preparing for this write operation, that error is returned in this parameter and the block in the writer parameter is NOT executed.
            // So in theory, we shouldn’t resume our continuation more than once.
            
            if let error = error {
                continuation.resume(throwing: error)
                // This is the line that I have not been able to test.
            }
        })
    }
}

现在我正在为这个逻辑编写单元测试。

代码语言:javascript
复制
final class FileCoordinatorTests: XCTestCase {
    
    static let testDirectoryURL: URL = {
        var url = NSPersistentContainer.defaultDirectoryURL().appendingPathComponent("EssentialHelpersTests", isDirectory: true)
        url = url.appendingPathComponent("FileCoordinatorTests", isDirectory: true)
        
        return url
    }()
    
    override func setUpWithError() throws {
        // Create a directory for this test class.
        try FileManager.default.createDirectory(at: Self.testDirectoryURL, withIntermediateDirectories: true)
    }
    
    override func tearDownWithError() throws {
        // Delete a directory after each test.
        try FileManager.default.removeItem(at: Self.testDirectoryURL)
    }
    
    func test_FileWritingCoordination() async throws {
        // given
        let data = Data("testData".utf8)
        let fileName = UUID().uuidString
        let url = Self.testDirectoryURL.appendingPathComponent(fileName)
        
        // when
        try await FileCoordinator.shared.coordinateWriting(of: data, to: url)
        
        // then
        XCTAssertTrue(FileManager.default.fileExists(atPath: url.path))
    }
    
    func test_FileWritingCoordinationWithError() async {
        // given
        let data = Data("testData".utf8)
        let urlWeDoNotHavePermissionToWriteTo = URL(fileURLWithPath: "/dev/null")
        var error: Error?
        
        // when
        do {
            try await FileCoordinator.shared.coordinateWriting(of: data, to: urlWeDoNotHavePermissionToWriteTo)
        } catch let err {
            error = err
        }
        
        // then
        XCTAssertNotNil(error)
    }
}

我似乎想不出一种方法来模拟NSFileCoordinator的错误条件,所以它会将一个错误对象分配给我们提供的指针。文档称,当文件演示者在准备写操作时遇到问题时,会创建错误。但我一开始就不使用文件演示器。我正在使用这个API来验证我的代码,以防将来添加iCloud支持。

文档说,如果我们在协调器上调用cancel()方法,就会生成错误。但是,在我的代码上下文中,应该在哪里调用该方法呢?我试着在调用coordinate(writingItemAt:options:writingItemAt:options:error:byAccessor:)之后调用它,但这没有任何效果。

我担心如果出现错误,我的代码结构可能会导致连续误用(恢复两次)。即使如果存在错误(根据文档),处理文件操作的块也不会执行,但我无法确认这一点。

EN

回答 1

Stack Overflow用户

发布于 2022-07-26 10:50:50

您不应该直接对NSFileCoordinator进行单元测试。相反,您应该创建一个NSFileCoordinator符合的协议,并为单元测试注入一个符合相同协议的模拟。这将允许您在单元测试中控制所需的依赖行为,并测试FileCoordinator在特定依赖条件下的正确行为。

您也不应该使用单例,因为这会使依赖注入和单元测试更加困难。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73121638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档