1

IBoutletコントローラ クラスのすべての が NIB ファイルに正しく接続されていることを単体テストで確認したいと考えています。OCMock を使用してこれを行いたいと思いますがnil、NIB をロードした後ではなく、コントローラーの変数を単純にアサートできることはわかっています。これは、プロセスがどのように機能するかについての一般的な理解の問題です。私が理解している限り、これも機能するはずです。

NIBOnOffSwitchCellには File's Owner がありOnOffSwitchCellControllerます。これは私のテスト方法です:

- (void) testIBOutletCellIsWiredToXib {
    id mockController = [OCMockObject mockForClass:[OnOffSwitchCellController class]];
    [[mockController expect] awakeAfterUsingCoder:OCMOCK_ANY];
    [[mockController expect] setValue:OCMOCK_ANY forKey:@"cell"];
    [[mockController expect] setValue:OCMOCK_ANY forKey:@"thelabel"];
    [[mockController expect] setValue:OCMOCK_ANY forKey:@"theswitch"];

    NSArray* nibContents = [guiBundle loadNibNamed:@"OnOffSwitchCell"
                                             owner:mockController
                                           options:nil];
    assertThat(nibContents, isNot(nil));
    assertThatInt([nibContents count], is(equalToInt(1)));
    assertThat([nibContents objectAtIndex:0], is(instanceOf([OnOffSwitchCell class])));

    [mockController verify];
}

guiBundle存在し、有効な NSBundle オブジェクトであることが確認されています。

私が理解していることからloadNibNamed:owner:options:、NIB内のオブジェクトを逆シリアル化し、呼び出してから、それぞれawakeAfterUsingCoder:を呼び出してアウトレットを設定しsetValue:forKey:ます。

ロードされた NIB に実際に正しいオブジェクトが含まれていることを確認するために、さらに 3 つのアサートを追加しました。実際のコントローラーのインスタンスを追加すると、これらは OK を通過します。しかし、上記のようにモックを使用すると、ここまで到達しません。代わりに、テストは次のようにクラッシュします。

テスト ケース '-[OnOffSwitchCellControllerTestCase testIBOutletCellIsWiredToXib]' が開始されました。
 2011-01-14 10:48:35.364 GTMTest[67797:903] *** キャッチされない例外 'NSInternalInconsistencyException' によりアプリを終了します。
     理由: 'OCMockObject[OnOffSwitchCellController]:
              予期しないメソッドが呼び出されました: awakeAfterUsingCoder:<UINibDecoder: 0x500e800>
    予想: setValue:<OCMAnyConstraint: 0x4c718e0> forKey:@"cell"
    予想: setValue:<OCMAnyConstraint: 0x4c71ce0> forKey:@"thelabel"
    予想: setValue:<OCMAnyConstraint: 0x4c71ed0> forKey:@"theswitch"'
*** 最初のスロー時のコール スタック:
(
    0 CoreFoundation 0x00e3dbe9 __exceptionPreprocess + 185
    1 libobjc.A.dylib 0x00f925c2 objc_exception_throw + 47
    2 CoreFoundation 0x00e3db21 -[NSException raise] + 17
    3 GTMTest 0x0001a049 -[OCMockObject handleUnRecordedInvocation:] + 322
    4 GTMTest 0x00019aca -[OCMockObject forwardInvocation:] + 77
    5 CoreFoundation 0x00daf404 ___forwarding___ + 1124
    6 CoreFoundation 0x00daef22 _CF_forwarding_prep_0 + 50
    7 UIKit 0x0062394a UINibDecoderDecodeObjectForValue + 2438
    8 UIKit 0x00624693 -[UINibDecoder decodeObjectForKey:] + 398
    9 UIKit 0x0053cf43 -[UIRuntimeConnection initWithCoder:] + 212
    10 UIKit 0x0053d4b1 -[UIRuntimeEventConnection initWithCoder:] + 64
    11 UIKit 0x006239e4 UINibDecoderDecodeObjectForValue + 2592
    12 UIKit 0x006232dc UINibDecoderDecodeObjectForValue + 792
    13 UIKit 0x00624693 -[UINibDecoder decodeObjectForKey:] + 398
    14 UIKit 0x0053c200 -[UINib instanceiateWithOwner:オプション:] + 804
    15 UIKit 0x0053e081 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
    16 GTMTest 0x000140dc -[OnOffSwitchCellControllerTestCase testIBOutletCellIsWiredToXib] + 503
    17 GTMTest 0x000041f3 -[SenTestCase invokeTest] + 163
    18 GTMTest 0x0000479a -[GTMTestCase 呼び出しテスト] + 146
    19 GTMTest 0x00003e90 -[SenTestCase performTest] + 37
    20 GTMTest 0x00002f3d -[GTMIPhoneUnitTestDelegate runTests] + 1413
    21 GTMTest 0x000028fb - [GTMIPhoneUnitTestDelegate applicationDidFinishLaunching:] + 197
    22 UIKit 0x00347253 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1252
    23 UIKit 0x0034955e -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
    24 UIKit 0x00348ef0 -[UIApplication_run] + 452
    25 UIKit 0x0035542e UIApplicationMain + 1160
    26 GTMTest 0x00003500 メイン + 104
    27 GTMTest 0x0000273d 開始 + 53
    28??? 0x00000002 0x0 + 2
)
「NSException」のインスタンスをスローした後に呼び出される終了

awakeAfterUsingCoder:そのため、私は明らかに期待していたにもかかわらず、への呼び出しが予期しないものであると不平を言っています。

また、その期待を取り除き、モックを余分なメソッド呼び出しを報告しない素敵なモックに置き換えてみましたが、それでも中止setValue:forKey:され、呼び出されていないと報告されます。

ここで何が欠けていますか?

4

2 に答える 2

0

これをメイン システム スレッドで実行してみましたか? UIKit クラスをメイン スレッドからインスタンス化することはできません。GTM がどのようにそれを行うのかはわかりませんが、GHUnit を使用すると、次をテスト ケース クラスに入れることができます。

- (BOOL)shouldRunOnMainThread {
    /* Tell GHUnit to run on a separate thread */
    return YES;
}
于 2011-02-03T15:52:16.653 に答える