我正在对 Typhoon 程序集进行子类化,以便返回存根实现,用于单元测试目的。
我的程序集看起来像这样:
class RealAssembly : TyphoonAssembly {
public dynamic func instanceToStubOut() -> AnyObject {
return TyphoonDefinition.withClass(SomeRealWorldClass.self)
}
public dynamic func instanceToTest() -> AnyObject {
return TyphoonDefinition.withClass(ClassToTest.self, configuration: { (definition : TyphoonDefinition!) -> Void in
definition.useInitializer("initWithObjectToStub:", parameters: { (initializer : TyphoonMethod!) -> Void in
initializer.injectParameterWith(self.instancetoStubOut())
})
})
}
}
我的测试类仅用于测试 type 的实例ClassToTest
,并且我想使用初始化器注入的依赖于SomeRealWorldClass
要存根的 type 对象来测试它。因此,我将 RealAssembly 子类化,以便将instanceToStubOut()
其覆盖以返回我的存根对象。
class MyTestClass : XCTestCase {
var assembly : TestAssembly!
class TestAssembly : RealAssembly {
override dynamic func instanceToStubOut() -> AnyObject {
return TyphoonDefinition.withClass(TestClass.self)
}
}
@objc
class TestClass : NSObject, ClassToStubOut {
func methodToStubOut() { /* do nothing */ }
}
override func setUp() {
super.setUp()
self.assembly = TestAssembly().activate()
}
override func tearDown() {
self.assembly = nil
super.tearDown()
}
func testStuff() {
let testingInstance = self.assembly.instanceToTest()
XCTAssertTrue(testingInstance.doStuff(), "doStuff returns true")
}
}
我希望这会起作用,但事实并非如此。Typhoon 似乎注入了一个未初始化的对象,而不是调用 TestAssembly.instanceToStubOut()
难道我做错了什么?我应该采取不同的方法吗?
编辑:这里有一些代码可以粘贴到 Swift Playground 中来演示问题。最后一行显示c.otherInstance
返回nil
:
import Typhoon
@objc
class BaseClass : NSObject {
var otherInstance : OtherProtocol!
func doIt() -> String {
return self.otherInstance.doStuff()
}
}
@objc
protocol OtherProtocol {
func doStuff() -> String
}
@objc
class OtherImpl : NSObject, OtherProtocol {
func doStuff() -> String {
return "OtherClass"
}
}
@objc
class StubClass : NSObject, OtherProtocol {
func doStuff() -> String {
return "Stubbed out"
}
}
class BaseAssembly : TyphoonAssembly {
dynamic func baseObject() -> AnyObject {
return TyphoonDefinition.withClass(BaseClass.self,
configuration: { (def : TyphoonDefinition!) -> Void in
def.injectProperty("otherInstance", with: self.otherObject())
})
}
dynamic func otherObject() -> AnyObject {
return TyphoonDefinition.withClass(OtherImpl.self)
}
}
var assembly = BaseAssembly()
assembly.activate()
var b = assembly.baseObject() as! BaseClass
b.doIt()
@objc
class TestAssembly : BaseAssembly {
override func otherObject() -> AnyObject {
return TyphoonDefinition.withClass(StubClass.self)
}
}
var testAssembly = TestAssembly()
testAssembly.activate()
var c = testAssembly.baseObject() as! BaseClass
c.otherInstance // this shouldn't be nil