2016-08-12 17 views
5

Swiftでクラス拡張の単体テストを作成しようとしています。しかし、私は入れませんSwiftでクラス拡張の単体テストを書く

import XCTest 

class AlertTest: XCTestCase { 

    func testAlert() { 

     let alert = presentAlert("Presented Alert", "This is an Alert!") 

    } 

} 

:私は以下のコードを含む私のユニットテスト用のファイルを作成し

extension UIViewController { 

    func presentAlert(title: String, message : String) { 
     let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) 
      alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil)) 

     UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil) 

    } 
} 

:クラス拡張自体は、以下のような指定されたタイトルとメッセージをUIAlertを紹介します"Use of unresolved identifier 'presentAlert'"のエラーです。

public func presentAlert(title: String, message : String)

まだ運:私はこのSO threadに相談した後、自分の内線にpublicを追加してみました。誰もがいくつかの洞察力を持っている?これは、ビューコントローラで

import Foundation 

protocol Presentable {} 

extension UIViewController { 

    public func presentAlert(title: String, message : String) { 
     let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) 
      alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil)) 

     UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil) 

    } 
} 

、私は警告を表示する:@hkgumbsによって回答に基づいて

EDIT

が、これは私のアラート拡張のための私の現在のコードですまだ私のアラートを呼び出すための正しい方法でしょうか?

self.presentAlert("Invalid URL", message: "Please try again") 

第二に、あなたのコメントに基づいて、これは私がダミーの値にPresentableを呼び出すことによって理解何何ですが、SomethingPresentableは何のメンバーPresentAlertを持っていないとして、それが間違っています。私の理解に間違っているところ?

func testAlert() { 

    let app = XCUIApplication() 

    struct SomethingPresentable: Presentable {} 

    SomethingPresentable.presentAlert("Presented Alert", message: "This is an Alert!") 

    XCTAssert(app.alerts["Presented Alert"].exists) 
    app.alerts["Presented Alert"].tap(); 

} 

EDIT 2 @hkgumbs、あなたの最新のコメントをもとに、これは私が拡張のために持っているものです。

import Foundation 

protocol Presentable {} 

extension Presentable { 

    func presentAlert(title: String, message : String) { 
     let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert) 
      alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil)) 

     UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil) 

    } 
} 

そして、これは私からそれを呼び出すようにしようとしている方法ですViewController:

Presentable.presentAlert("Invalid URL", message: "Please try again") 

しかし、私はタイプSelf上のインスタンスメンバpresentAlertの「使用のエラーを取得するには、あなたをしました代わりにタイプSelfの変数を使用することを意味しますか?

次に、私はこのテストがどのように見えるかを推測していますか?

func testAlert() { 

    let app = XCUIApplication() 

    struct SomethingPresentable: Presentable {} 

    SomethingPresentable.presentAlert("Presented Alert", message: "This is an Alert!") 

    XCTAssert(app.alerts["Presented Alert"].exists) 
    app.alerts["Presented Alert"].tap(); 

} 
+0

あなたの拡張は 'UIViewController'にありますので、' UIViewController'でそれを呼び出す必要があります。あなたがそれを呼び出す方法は宣言にも一致しません。 – dan

+0

@danそのタイポをキャッチしてくれてありがとう...私はちょうど質問でそれを修正しました。ユニットテストでViewControllerで呼び出すのはどうですか? – narner

答えて

4

@danが示唆したように、あなたはからインスタンスUIViewControllerそれを呼び出す必要があります。

  1. presentAlert静的あなただけUIViewController.presentAlert
  2. メイクをすることができるようにしてください:あなたはそれを避けることができれば、通常、あなたはそれを避けるために、いくつかのオプションがありますので、ここでは、あなたのテストでフレームワークオブジェクトをインスタンス化する必要はありませんpresentAlertフリー機能(拡張に入れないでください)
  3. ではなく、プロトコルを拡張 - 私はこれが最もきれいオプション
だと思いますあなたが extension UIViewController: Presentable {}ことができ、それを必要とする時はいつでも次に
protocol Presentable {} 

extension Presentable { 
    func presentAlert(title: String, message : String) { /* ... */ } 
} 

、。あなたのテストでは、ダミークラスを使うことができます。このアプローチの利点は、必要に応じて、その関数をグローバルに公開しなくても、必要に応じて再利用できることです。

補遺我々はプロトコルを拡張する場合、我々は「このプロトコルを実装して何が自由のために、このメソッドを取得します。」と言っている

ここでのトリックは、このプロトコルが空であり、したがって、実装が非常に容易であるということです。

extension YourViewController: Presentable {} 
+0

これは私にいくつかの意味を作り始めています、ありがとう。あなたのための2つの質問: 1)私が代わりにプロトコルを作る場合、私はどのように私のView Controllerから呼び出すでしょうか?現在、拡張子を呼び出すと、次のようになります。 self.presentAlert(「無効なURL」、メッセージ:「もう一度やり直してください」)これを呼び出すためにダミーのクラスを使用して 2)私はあなたが何を意味するか正確にはわかりません私のテストからのプロトコル...あなたはさらに詳しく説明できますか? スウィフトの複雑さに慣れようとしています。 – narner

+0

この回答を受け入れて幸いです。もう少し理解が必要なだけ...ありがとう! – narner

+1

@narner sure! 1)このプロトコルを拡張する場合、同じ方法でアクセスすることができます:拡張YourViewController:Presentable {} '。 2)あなたのテストでダミー値を作るのと同じ考え方です: 'struct SomethingPresentable:Presentable {}'。次に 'ViewController'の代わりに' presentAlert'を呼び出します。 – hkgumbs

関連する問題