我正在尝试为用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
的方式。我正在寻找一种方法,可以将模拟系统库注入我的自定义类中,以方便测试,而无需实际让测试代码侵入主应用程序代码。
最佳答案
我解决了问题!在LocalStorage
类中,我先前在初始化程序中将NSFileManager实例化为fileMgr = NSFileManager()
。我将初始化程序更改为init(fileManager: NSFileManager)
,并将NSFileManager实例分配给fileMgr
。我必须在整个代码中用LocalStorage()
替换对LocalStorage(NSFileManager())
的调用。现在,在测试中,我只需使用模拟的NSFileManager(如LocalStorage(MockNSFileManager())
)初始化LocalStorage。之所以可行,是因为从技术上讲,MockNSFileManager
是NSFileManager
class MockNSFileManager: NSFileManager {
在MockFileManager类声明中。
关于ios - 如何在不使用任何模拟库的情况下模拟iOS Swift中的系统库?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40232090/