iOS 10のSwift 3アプリケーションでは、NotificationControllerを使用してViewControllerをテストしようとしています。スウィフトユニットテストでは、アプリケーションとユニットテストターゲット間のクラスキャストエラーが発生しました
私のViewControllerの初期化では、プロバイダーにデータを照会し、同期応答を受信します。プロバイダは、Webへの非同期呼び出しを使用してデータを更新しようとし、変更された場合、ViewControllerによってキャッチされる通知を送信します。ここに私のViewControllerの初期の作品である:
class func instantiateWithId(_ id: String, provider: DataProvider) -> MyViewController {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle(for:MyViewController.self));
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerId") as! MyViewController;
controller.dataProvider = provider;
controller.objectId = id;
controller.object = controller.dataProvider!.getObject(id: id, completion: controller.refreshObject);
return controller;
}
初期化の後、私は正常に動作して通知オブザーバを登録します。
NotificationCenter.default.addObserver(self, selector: #selector(self.catchNotification), name: NotificationName, object: nil);
ここでのViewControllerに通知を処理する機能があります。正常に動作している:
func catchNotification(notification: NSNotification) -> Void {
guard (notification.name == NotificationName) else {return;}
let info = notification.userInfo as! [String: Any];
if info.count > 0 {
guard (info[objectId] != nil) else {return;}
if let value = info[objectId] as! MyCustomStruct? {
self.refreshData(updated: value);
}
}
}
をプロバイダでは、私は、Webからの非同期応答を受け取るとすぐに、私はのUserInfoに新しいデータで通知を送信:
var dict = Dictionary<String, myCustomStruct>();
dict.updateValue(newData, forKey: newData.objectId);
let msg = Notification(name: NotificationName, object: nil, userInfo: dict)
NotificationCenter.default.post(msg);
すべてのコードは上記の作業をしています罰金、しかし、私のユニットテストで私は通知がunittestのターゲットのためのmyCustomStructは、アプリケーション・ターゲットにmyCustomStructにキャストすることができないことを言って、私のViewControllerでcatchedされたエラーを取得:
Could not cast value of type ‘ApplicationUnitTests.MyCustomStruct’ (0x1161fa828) to ‘Application. myCustomStruct' (0x1057fd6d0).
私はすでにチェックしており、CustomStructは2つのターゲットで利用可能です。
func testViewControllerInitialization() {
let fixture = MockDataProvider();
let sutId = fixture.testId;
let sut = MyViewController.instantiateWithId(sutId, provider: fixture)
_ = sut.view;
XCTAssertNotNil(sut, "SUT not initialized");
XCTAssertNotNil(sut.object, "Object Not Loaded!");
XCTAssertEqual(sutId, sut.object!.objectId, "Differente ObjectId expected!");
let newValue = "changed";
var nextFixture = fixture.getObject(objectId: sutId, completion: {(result) in return;});
nextFixture.name = newValue;
fixture.refreshObject(newData: nextFixture); <- This function send the notification
sleep(1);
XCTAssertEqual(newValue, sut.object!.name);
}
このエラーは完全に問題を記述しています:appは 'Application.myCustomStruct'を期待し、' ApplicationUnitTests.MyCustomStruct'を送信しています。テストで 'Application.myCustomStruct'を使用できませんか? –
ポイントは:私はApplicationUnitTests.MyCustomStructsを持っていません。私はちょうどApplication.myCustomStructを持っています。私が理解しているように、ApplicationUnitTestsターゲットはすべてのApplication Targetクラスをインポートします。テストターゲットでクラスを複製する必要がある場合は、ユニットテストの全体的な考え方が失われます。 –
アプリケーションファイル(およびそれに含まれるクラスと他のタイプ)は、ユニットテストターゲットに自動的にインポートされません。新しいファイルを作成するときに、そのファイルの対象となるターゲットを指定します。単体テストターゲットを追加しない場合は、後でインスペクタから追加することができます(ファイルを選択し、インスペクタを開き、テストターゲットをチェックします)。 –