我正在尝试单独测试我自己的一个类,它正在调用第三方类的方法:
- FIRAuth.auth()?.signInAnonymously() { (user,error) in
- //
- }
我正在使用基于协议的依赖注入来实现这一点:
- protocol FIRAuthProtocol {
- func signInAnonymously(completion: FIRAuthResultCallback?)
- }
- extension FIRAuth: FIRAuthProtocol {}
- class MyClass {
- private var firAuth: FIRAuthProtocol
- init(firAuth: FIRAuthProtocol) {
- self.firAuth = firAuth
- }
- func signIn() {
- firAuth.signInAnonymously() { (user,error) in
- //
- }
- }
- }
- class MockFIRAuth: FIRAuthProtocol {
- var signInAnonymouslyCalled = false
- func signInAnonymously(completion: FIRAuthResultCallback? = nil) {
- signInAnonymouslyCalled = true
- }
- }
- class MyClassSpec: QuickSpec {
- override func spec() {
- describe("MyClass") {
- describe(".signIn()") {
- it("should call signInAnonymously() on firAuth") {
- let mockFIRAuth = MockFIRAuth()
- let myClass = MyClass(firAuth: mockFIRAuth)
- expect(mockFIRAuth.signInAnonymouslyCalled).to(beFalse())
- myClass.signIn()
- expect(mockFIRAuth.signInAnonymouslyCalled).to(beTrue())
- }
- }
- }
- }
- }
到现在为止还挺好!
现在,我希望我的mockFIRAuth返回FIRUser的一个实例.
这是我的问题:我自己无法创建FIRUser的实例.
仅供参考:公共类型FIRAuthResultCallback =(FIRUser?,错误?) – > Swift.Void
如果发现这篇很棒的文章解释了如何在第三方类上创建一个方法而不是一个类型. http://masilotti.com/testing-nsurlsession-input/
也许我的情况与文章的情况不同,但这是我对此的看法:
我已经定义了FIRUserProtocol:
- protocol FIRUserProtocol {
- var uid: String { get }
- }
- extension FIRUser: FIRUserProtocol {}
我更新了FIRAuthProtocol以使用FIRUserProtocol而不是FIRUser调用完成处理程序:
- protocol FIRAuthProtocol {
- func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)?)
- }
我更新了FIRAuth扩展以支持修改后的协议.我新定义的方法调用signInAnonymously的默认实现:
- extension FIRAuth: FIRAuthProtocol {
- func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
- signInAnonymously(completion: completion)
- }
- }
- class MockFIRAuth: FIRAuthProtocol {
- var signInAnonymouslyCalled = false
- func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
- signInAnonymouslyCalled = true
- }
- }
现在,当我运行我的测试时,一切都停止了:
线程1:EXC_BAD_ACCESS(代码= 2,地址= 0x7fff586a2ff8)
请指教!
更新
在我的FIRAuthProtocol方法中重命名完成参数标签后,一切似乎都按预期工作:
- protocol FIRAuthProtocol {
- func signInAnonymously(completionWithProtocol: ((FIRUserProtocol?,Error?) -> Void)?)
- }
- extension FIRAuth: FIRAuthProtocol {
- func signInAnonymously(completionWithProtocol: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
- signInAnonymously(completion: completionWithProtocol)
- }
- }
这解决了我现在的问题,但我仍然想知道为什么我的第一次尝试不成功.这是否意味着它们的闭包中具有不同参数类型的两个方法不能被分开,这导致我的应用程序崩溃?
我终于找到了解决这个问题的优雅方法.
- protocol FIRAuthProtocol {
- func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)?)
- }
- extension FIRAuth: FIRAuthProtocol {
- func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
- let completion = completion as FIRAuthResultCallback?
- signInAnonymously(completion: completion)
- }
- }