如何在不使用任何模拟库的情况下在iOS Swift中模拟系统库?

时间:2016-10-25 05:36:39

标签: ios swift unit-testing mocking

我正在尝试为我在Swift 2.2中编写的个人项目编写单元测试。该项目的一部分是自定义类LocalStorageManager,它使用NSFileManager执行文件IO操作,并为要访问的其他应用程序公开非常简化的文件交互。现在我需要模拟NSFileManager,因为我不希望我的测试创建真实文件。我一直在尝试,但我不喜欢它。

我用以下格式写了一个模拟类:

import Foundation

class MockNSFileManager: NSFileManager {

    override init() {
        // do nothings master!!
    }

    override func createFileAtPath(path: String, contents data: NSData?, attributes attr: [String : AnyObject]?) -> Bool {
        print("file mock created")
        return true
    }

    override func fileExistsAtPath(path: String, isDirectory: UnsafeMutablePointer<ObjCBool>) -> Bool {
        print("does the file exists?")
        return false
    }

    override func fileExistsAtPath(path: String) -> Bool {
        print("the file exists")
        return true
    }

    override func createDirectoryAtPath(path: String, withIntermediateDirectories createIntermediates: Bool, attributes: [String : AnyObject]?) throws {
        print("successfully maybe...")
    }

    override func contentsAtPath(path: String) -> NSData? {
        print("returning some fancy contents")
        return NSData()
    }

    override func removeItemAtPath(path: String) throws {
        print("removing item at the path")
    }
}

LocalStorageManager中,我实施了init(fileManager: NSFileManager)

在我的单元测试中,我将LocalStorage初始化为LocalStorage(fileManager: MockNSFileManager())

一切都运作良好并且符合预期。但是,我不喜欢我的测试代码如何侵入我的应用程序生产代码。在LocalStorage课程中,我不喜欢当我的应用不要求它运行时我需要如何实现init

我正在寻找一种方法,使我可以将模拟系统库注入我的自定义类,以便于测试而不会让测试代码侵入主应用程序代码。

1 个答案:

答案 0 :(得分:0)

我解决了这个问题!在LocalStorage类中,我先前在初始化程序中将NSFileManager实例化为fileMgr = NSFileManager()。我将初始化程序更改为init(fileManager: NSFileManager),并将NSFileManager实例分配给fileMgr。我必须使用LocalStorage()替换整个代码中的LocalStorage(NSFileManager())来电。现在在测试中,我只需使用像LocalStorage(MockNSFileManager())这样的模拟NSFileManager初始化LocalStorage。这是有效的,因为从技术角度来说,MockNSFileManager因为行<{p}}而属NSFileManager

class MockNSFileManager: NSFileManager {

在MockFileManager类声明中。