QuickでNSDictionaryの中身をテストしたい時にコンパイルエラーが出たので調べてみた

More than 3 years have passed since last update.

SwiftでSpec風なテストが書けるQuick(Nimble)のMatcherを使う時にコンパイルエラーになってしまったので調べたメモ。

Quickについてはこことかで


初めに書いたの:

class HogeSpec: QuickSpec {

let dic = NSMutableDictionary()
dic.setValue("hoge", forKey("name"))

it("nameのキーで何か文字列が入ってるのを確認したい") {
expect(dic["name"]).to(beAKindOf(NSString.self))
// ↑ コンパイルエラー: Could not find member 'to'
}
}

なんでコンパイルエラーになるのか調べてみた。


beAKindOfの宣言を見てみた

public func beAKindOf(expectedClass: AnyClass) -> MatcherFunc<NSObject>

型パラメータがNSObjectのMatcherFuncを返してる。


toの宣言を見てみた

public struct Expectation<T> {

// 中略
public func to<U where U: Matcher, U.ValueType == T>(matcher: U)

型パラメータの制約(where)で、U.ValueType、つまりmatcherの型パラメータが、Tと同じじゃないとダメ。

Expectationは expect(...) で返されるやつ

NSDictionaryAnyObject!を返すので、T(AnyObject)U.ValueType(NSObject) と違うのでこの型の組み合わせだと to は呼べない。

じゃあNSObjectにキャストしてやればいいじゃん。


書き換えた:

class HogeSpec: QuickSpec {

let dic = NSMutableDictionary()
dic.setValue("hoge", forKey("name"))

it("nameのキーで何か文字列が入ってるのを確認したい") {
expect(dic["name"] as NSObject!).to(beAKindOf(NSString.self))
}
}

なんでAnyObjectじゃなくてNSObjectになってるのかと思ったけどObjective-Cからでも使えるようにかな?