在Swift中模拟第三方类(Firebase)

前端之家收集整理的这篇文章主要介绍了在Swift中模拟第三方类(Firebase)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试单独测试我自己的一个类,它正在调用第三方类的方法
  1. FIRAuth.auth()?.signInAnonymously() { (user,error) in
  2. //
  3. }

我正在使用基于协议的依赖注入来实现这一点:

  1. protocol FIRAuthProtocol {
  2. func signInAnonymously(completion: FIRAuthResultCallback?)
  3. }
  4. extension FIRAuth: FIRAuthProtocol {}
  5.  
  6. class MyClass {
  7. private var firAuth: FIRAuthProtocol
  8.  
  9. init(firAuth: FIRAuthProtocol) {
  10. self.firAuth = firAuth
  11. }
  12.  
  13. func signIn() {
  14. firAuth.signInAnonymously() { (user,error) in
  15. //
  16. }
  17. }
  18. }
  19.  
  20. class MockFIRAuth: FIRAuthProtocol {
  21. var signInAnonymouslyCalled = false
  22.  
  23. func signInAnonymously(completion: FIRAuthResultCallback? = nil) {
  24. signInAnonymouslyCalled = true
  25. }
  26.  
  27. }
  28.  
  29. class MyClassSpec: QuickSpec {
  30. override func spec() {
  31. describe("MyClass") {
  32. describe(".signIn()") {
  33. it("should call signInAnonymously() on firAuth") {
  34. let mockFIRAuth = MockFIRAuth()
  35. let myClass = MyClass(firAuth: mockFIRAuth)
  36. expect(mockFIRAuth.signInAnonymouslyCalled).to(beFalse())
  37. myClass.signIn()
  38. expect(mockFIRAuth.signInAnonymouslyCalled).to(beTrue())
  39. }
  40. }
  41. }
  42. }
  43. }

到现在为止还挺好!
现在,我希望我的mockFIRAuth返回FIRUser的一个实例.
这是我的问题:我自己无法创建FIRUser的实例.

仅供参考:公共类型FIRAuthResultCallback =(FIRUser?,错误?) – > Swift.Void

如果发现这篇很棒的文章解释了如何在第三方类上创建一个方法而不是一个类型. http://masilotti.com/testing-nsurlsession-input/
也许我的情况与文章的情况不同,但这是我对此的看法:

我已经定义了FIRUserProtocol:

  1. protocol FIRUserProtocol {
  2. var uid: String { get }
  3. }
  4. extension FIRUser: FIRUserProtocol {}

我更新了FIRAuthProtocol以使用FIRUserProtocol而不是FIRUser调用完成处理程序:

  1. protocol FIRAuthProtocol {
  2. func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)?)
  3. }

我更新了FIRAuth扩展以支持修改后的协议.我新定义的方法调用signInAnonymously的默认实现:

  1. extension FIRAuth: FIRAuthProtocol {
  2. func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
  3. signInAnonymously(completion: completion)
  4. }
  5. }

最后,我更新了MockFIRAuth以支持修改后的协议:

  1. class MockFIRAuth: FIRAuthProtocol {
  2. var signInAnonymouslyCalled = false
  3. func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
  4. signInAnonymouslyCalled = true
  5. }
  6. }

现在,当我运行我的测试时,一切都停止了:


线程1:EXC_BAD_ACCESS(代码= 2,地址= 0x7fff586a2ff8)

请指教!

更新

在我的FIRAuthProtocol方法重命名完成参数标签后,一切似乎都按预期工作:

  1. protocol FIRAuthProtocol {
  2. func signInAnonymously(completionWithProtocol: ((FIRUserProtocol?,Error?) -> Void)?)
  3. }
  4.  
  5. extension FIRAuth: FIRAuthProtocol {
  6. func signInAnonymously(completionWithProtocol: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
  7. signInAnonymously(completion: completionWithProtocol)
  8. }
  9. }

解决了我现在的问题,但我仍然想知道为什么我的第一次尝试不成功.这是否意味着它们的闭包中具有不同参数类型的两个方法不能被分开,这导致我的应用程序崩溃?

我终于找到了解决这个问题的优雅方法.
  1. protocol FIRAuthProtocol {
  2. func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)?)
  3. }
  4.  
  5. extension FIRAuth: FIRAuthProtocol {
  6. func signInAnonymously(completion: ((FIRUserProtocol?,Error?) -> Void)? = nil) {
  7. let completion = completion as FIRAuthResultCallback?
  8. signInAnonymously(completion: completion)
  9. }
  10. }

这样,就不需要改变函数名称或参数标签.

猜你在找的Swift相关文章