在单元测试中模拟 UserDefaults 对象返回 _ArrayBuffer
Posted
技术标签:
【中文标题】在单元测试中模拟 UserDefaults 对象返回 _ArrayBuffer【英文标题】:Mock UserDefaults Object In Unit Test Returning _ArrayBuffer 【发布时间】:2017-08-02 04:15:11 【问题描述】:我试图在我的单元测试中删除对操作系统对象(如 URLSessions 和 UserDefaults)的依赖关系。我一直试图将预缓存的数据模拟到我为测试目的而制作的模拟 UserDefaults 对象中。
我创建了一个具有编码和解码功能的测试类,并将模拟数据存储在一个成员变量中,该成员变量是一个 [String: AnyObject] 字典。在我的应用中,启动时它会检查缓存中的数据,如果找到,则会跳过网络调用。
我所能得到的只是 nil 或这个持续错误:
致命错误:NSArray 元素无法匹配 Swift Array 元素 输入
查看调试器,解码器应该返回一个自定义类型“问题”的数组。相反,我得到一个 _ArrayBuffer 对象。
奇怪的是,如果我的应用程序将数据加载到我的模拟 userdefaults 对象中,它可以正常工作,但是当我将对象硬编码到其中时,我会收到此错误。
这是我模拟 UserDefaults 对象的代码:
class MockUserSettings: DataArchive
private var archive: [String: AnyObject] = [:]
func decode<T>(key: String, returnClass: T.Type, callback: (([T]?) -> Void))
print("attempting payload from mockusersettings with key: \(key)")
if let data = archive[key]
callback(data as! [T])
else
print("Found nothing for: \(key)")
callback(nil)
public func encode<T>(key: String, payload: [T])
print("Adding payload to mockusersettings with key: \(key)")
archive[key] = payload as AnyObject
以及我想要通过的测试:
func testInitStorageWithCachedQuestions()
let expect = XCTestExpectation(description: "After init with cached questions, initStorage() should return a cached question.")
let mockUserSettings = MockUserSettings()
var questionsArray: [Question] = []
for mockQuestion in mockResponse
if let question = Question(fromDict: mockQuestion)
questionsArray.append(question)
mockUserSettings.encode(key: "questions", payload: questionsArray)
mockUserSettings.encode(key: "currentIndex", payload: [0])
mockUserSettings.encode(key: "nextFetchDate", payload: [Date.init().addingTimeInterval(+60)])
let questionStore = QuestionStore(dateGenerator: Date.init, userSettings: mockUserSettings)
questionStore.initStore() (question) in
let mockQuestionOne = Question(fromDict: self.mockResponse[0])
XCTAssertTrue(question == mockQuestionOne)
XCTAssert(self.numberOfNetworkCalls == 0)
expect.fulfill()
wait(for: [expect], timeout: 1.0)
如果有人可以帮助我弄清楚我做错了什么,我将不胜感激。我是否正确存储了我的模拟对象?这个 ArrayBuffer 和 ArrayBridgeStorage 是什么东西??
【问题讨论】:
【参考方案1】:我解决了我的问题。我的自定义类同时针对我的应用程序和测试。在单元测试中,我使用的是测试目标版本的类构造函数,而不是主应用程序的版本。
因此,要从中吸取的教训就是使用@testable import
,而不是让您的应用类针对测试。
【讨论】:
以上是关于在单元测试中模拟 UserDefaults 对象返回 _ArrayBuffer的主要内容,如果未能解决你的问题,请参考以下文章