我有一個問題,我試圖測試一個有兩個依賴關係的類。依賴關係實現一個協議,並且我將兩個'模擬'對象也傳遞給我的被測對象。我在下面的一個小測試應用程序中轉載了這個問題。使用協議擴展的嘲弄依賴不會調用模擬方法
import UIKit
// first dependency of `Data` (below)
protocol Local {}
extension Local {
// the default method that I want my app to use when running a
// `normal` execution mode, i.e. not a test
func isCached (url : NSURL) -> Bool {
return true
}
}
// the actual class definition that the app normally runs
class LocalImpl : Local {}
// much the same as `Local` above
protocol Server {}
extension Server {
func getURL (url : NSURL) -> NSData? {
// todo
return nil
}
}
class ServerImpl : Server {}
// The object that I want to test.
protocol Data {
var local : Local { get set }
var server : Server { get set }
}
extension Data {
func getData (url : NSURL) -> NSData? {
if local.isCached(url) {
return nil
} else {
return server.getURL(url)
}
}
}
class DataImpl : Data {
var local : Local
var server : Server
init() {
local = LocalImpl()
server = ServerImpl()
}
init (server : Server, local : Local) {
self.server = server
self.local = local
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let data : Data = DataImpl()
data.getData(NSURL(string: "http://google.com")!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
然後,在我的測試
@testable import TestingTests
class Test: XCTestCase {
// the mock server instance I want to use in my test
class MockServer : Server {
static var wasCalled = false
func getURL(url: NSURL) -> NSData? {
MockServer.wasCalled = true
return nil
}
}
// the local instance I want to use in my test (with overridden protocol function)
class MockLocal : Local {
func isCached (url : NSURL) -> Bool {
return false
}
}
func testExample() {
let data = DataImpl(server: MockServer(), local: MockLocal())
data.getData(NSURL(string: "http://hi.com")!)
XCTAssert(MockServer.wasCalled == true)
}
}
以上測試就會失敗。當使用調試器逐步完成測試時,將在Local對象上調用isCached
的協議定義。換句話說,「默認」實現運行而不是我在測試中定義的實現。
如果我在我的測試文件中設置斷點,Data
對象設置正確,並設置了我的模擬。但是,一旦我進入getData
函數,試圖從LLDB打印data.local或data.server將產生錯誤的訪問錯誤(應用程序實際上不會崩潰,但調試器無法打印該值)
是我在這裏丟失一些東西,或者有人可以向我解釋爲什麼你不能這樣做?
與斯威夫特2
看看這個[SO](http://stackoverflow.com/questions/31795158/swift-2-protocol -extension-not-calling-overriden-method-correctly)文章。這可能是你的問題。 –
也許,雖然我沒有試圖在鏈接文章中使用多態。我沒有使用任何子類,只是試圖使用所有實現相同協議的不同類。 – bendecoste