2017-03-18 12 views
1

キーボードとプレゼンテーションコントローラが正しくトリガされるようにユニットテストを作成しようとしていますが、どのようにUIWindow作品に関連しています。私はQuickNimbleを使用していますが、私はバニラXCTestでテストして同じ問題を抱えています。ユニットテストでiOSのビューコントローラとキーボードが提示されました

マイコード:まず

import Quick 
import Nimble 

class TestSpec: QuickSpec { 
    override func spec() { 

     let sut = UIViewController() 

     // The window is nil when this test is run in isolation 
     UIApplication.shared.keyWindow?.rootViewController = sut 

     // This does not work either 
     let window = UIWindow(frame: UIScreen.main.bounds) 
     window.rootViewController = sut 
     window.makeKeyAndVisible() 

     describe("ViewController") { 

      it("presents a UIAlertController") { 
       let alert = UIAlertController(title: "Test", message: "This is a test", preferredStyle: .alert) 
       let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) 
       alert.addAction(okAction) 

       sut.present(alert, animated: true, completion: nil) 
       expect(sut.presentedViewController).toEventually(beAnInstanceOf(UIAlertController.self)) 
      } 
     } 
    } 
} 

、私は他のView Controllerを提示するからそれを防ぐウィンドウにビューコントローラを入れていませんでした。今私は窓の中に入れようとしていますが、それはどちらも働いていません。このテストを単独で実行すると、ウィンドウは常にゼロになります。私は他のテストの束とそれを実行するとき、ウィンドウは時々nilではありませんが、テストはまだ失敗します。テストが終わった短い期間がありましたが、何らかの理由でそれをもう複製できません。

何がいいですか?

+0

はあなたですテストを実行しているときにホストアプリケーションが実行されていますか? – DisableR

答えて

1

この質問を開いていただきありがとうございます。これにぶつからなかった場合、私はUIWindow問題については考えていません。

beforeEach { 
    let window = UIWindow(frame: UIScreen.main.bounds) 
    window.makeKeyAndVisible() 
    window.rootViewController = sut 
    _ = sut.view 
} 

2つのことを注意することは:私のテストでは

let window = UIWindow(frame: UIScreen.main.bounds) 

UIApplication.shared.keyWindowの値が

はあなたのコードを少しいじる後、私はこれを行うことによって、私のテストパスを作ることができましたnil。私はそれがあなたと同じであるかどうか確かではありません。私はprevent the unit tests from loading the UIAppDelegateと関係があるかもしれません。

また、ウィンドウインスタンスはspecクラスによって保持されないことに注意してください。私はこれが不要であると信じます。なぜなら、キーウィンドウにUIApplicationインスタンスがそれを保持し、UIApplicationが解放されないからです。

_ = sut.view 

この行はトリックです。それは実際にビュー階層に追加されているのビューコントローラ結果のビューにアクセスしようとすると、(1がそうなるだろう警告を解決してより多くの情報hereを、:これは役立ちます

Warning: Attempt to present <BarViewController: 0x7f87a9c5def0> 
on <FooViewController: 0x7f87a9d5e320> whose view is not in the window 
hierarchy! 

希望;)

+1

ありがとう! これまで私はこれまでのところ答えをあきらめてからあきらめました。 – Erik

+0

ありがとう@モカジオ!私はEarlGreyを使用しており、テスト間で再初期化に問題がありました。 UIの作成をテストセットアップに移動することで修正されました。 – markand

0

あなたのアプリのデリゲートをシングルトンにすることができます。 この場合、アプリケーションのウィンドウにアクセスできます。例えば。

[AppDelegate sharedDelegate].window 

別のアプローチは、あなたのテストで新しいウィンドウを作成し、それkeyAndVisible作り、それにrootViewControllerを割り当て、独立して、それに対処することです。