2016-05-03 14 views
2

私は単体テストであるSwiftクラスを持っています。このクラスの主な目的は、HTTP呼び出しを行うことです。私はちょうどMockingjayを使ってすべてのネットワーキング要求を嘲笑し終えましたが、今後のリクエストを模擬することを忘れないようにしたいと思います。私が初期の嘲笑をしている間、私は使用しているベースURLを、動作しないURLに置き換えましたが、私はのためにの場所に保持したいと思います。テスト対象のクラスは次のようになります。テスト用のSwiftクラスプロパティをオーバーライドする方法

public class MyWebServiceWrapper { 
    ... 

    public class var baseURL: String { 
     return "https://api.thesite.com" 
    } 

    ... 
} 

私はbaseURLの実装を置き換えるためのObjective-CクラスからOCMockを使用することを試みた、と私は、同様の方法スウィズリングas described on NSHipsterを使用してみました(IクラスをNSObjectから派生させ、上記のプロパティの代わりにbaseURLをメソッドに置き換えました。特に、クラスがNSObjectのサブクラスである必要はないので、私はむしろうまくいきません。

これは、私が試したスウィズルを実行するために使用したコードです。これは効果がありません。 (スウィフト中)

​​3210

これだった私のスウィズリングの試み:以下の両方試みたソリューションについては、私は(それがどちらのアプローチがスウィフトプロパティまたは純粋スウィフトのクラスでうまく機能するであろうように見えたので)そのようにテスト中の私のクラスを書き直し。ログに基づいて、毎晩elseというステートメントが表示され、何が起こっているか把握するのに役立ちます。

extension MyWebServiceWrapper { 

    public override class func initialize() { 
     struct Static { 
      static var token: dispatch_once_t = 0 
     } 

     if self !== MyWebServiceWrapper.self { 
      return 
     } 

     dispatch_once(&Static.token) { 
      NSLog("Replacing MyWebServiceWrapper base URL...") 
      let originalSelector = #selector(baseURLValue) 
      let swizzledSelector = #selector(networkFreeBaseURL) 

      guard let klass = object_getClass(self) else { 
       return 
      } 

      let originalMethod = class_getClassMethod(klass, originalSelector) 
      let swizzledMethod = class_getClassMethod(klass, swizzledSelector) 

      let didAddMethod = class_addMethod(klass, originalSelector, 
               method_getImplementation(swizzledMethod), 
               method_getTypeEncoding(swizzledMethod)) 

      if didAddMethod { 
       NSLog("MyWebServiceWrapper method added") 
       class_replaceMethod(klass, swizzledSelector, method_getImplementation(originalMethod), 
            method_getTypeEncoding(originalMethod)) 
      } else { 
       method_exchangeImplementations(originalMethod, swizzledMethod) 
       NSLog("MyWebServiceWrapper implementation replaced") 
      } 
     } 
    } 

    class func networkFreeBaseURL() -> String { 
     return "https://tests-shouldnt-hit-the-network.com" 
    } 

} 

これは(Objective-Cの)OCMockを使用してメソッドを置き換えようとした方法です。このコードは、単体テストの設定時に呼び出されます。

id wrapperMock = OCMClassMock([MyWebServiceWrapper class]); 
OCMStub(ClassMethod([wrapperMock baseURLValue])).andReturn(@"https://tests-shouldnt-hit-the-network.com"); 

baseURLから無効な値を返すという目標を達成する正しい方法はありますか?

+0

あなたは、別の方法を見つける必要がある:( あなたがどんな解決策を見つけるか – denis631

+1

denis631 @私はまだです?答えを使用して私は – Dov

+0

悲しい...それはちょうど右のように見えないが、あなたが知っている... GTD:GET THINGS Done :) – denis631

答えて

1

テスト中のクラスのコードを修正する必要があったので、私はそれに完全に満足していません(別の答えが大好きです)。私はオーバーライド変数internalを作ったので、それは仕事を完了させ、非テストコードによって容易に虐待されることはありません。

public class MyWebServiceWrapper { 
    ... 

    /// Only use for testing! 
    internal static var baseURLOverride: String? 

    public class var baseURL: String { 
     return baseURLOverride ?? "https://api.thesite.com" 
    } 

    ... 
} 

そして、私の試験構成の内側から:それ以外の場合は、回避策だから

@testable 
import MyFramework 

... 

// Inside test configuration 
MyWebServiceWrapper.baseURLOverride = "https://tests-shouldnt-hit-the-network.com"