1

私は、OCMock を使用して applicationDidFinishLaunching デリゲートを単体テストする方法を考え出そうとしています。私の NSWindowController はここでインスタンス化されており、テストしたいと思います。ここに私のテストコードがあります:

id mockWindowController = [OCMockObject niceMockForClass:[URLTimerWindowController class]];
[[mockWindowController expect] showWindow:self];
NSUInteger preRetainCount = [mockWindowController retainCount];

[appDelegate applicationDidFinishLaunching:nil];

[mockWindowController verify];

テストを実行すると、次のエラーが表示されます。

「OCMockObject[URLTimerWindowController]: 予期されるメソッドが呼び出されませんでした: showWindow:-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]」

ログに詳細が表示されます。

"Test Case '-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]' started.
2011-04-11 08:36:57.558 otest-x86_64[3868:903] -[URLTimerWindowController loadWindow]: failed to load window nib file 'TimerWindow'.
Unknown.m:0: error: -[URLTimerAppDelegateTests testApplicationDidFinishLaunching] : OCMockObject[URLTimerWindowController]: expected method was not invoked: showWindow:-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]
Test Case '-[URLTimerAppDelegateTests testApplicationDidFinishLaunching]' failed (0.005 seconds).
"

そのため、NIB の読み込みに失敗していることがわかります。では、単体テスト中にロードしたり、何らかの方法でロードをモックしたりするにはどうすればよいですか? OCMock のドキュメント、ユニット テストに関する Chris Hanson のヒント、および同様の動作をする WhereIsMyMac ソース コードを含むその他のリソースをいくつか確認しました。ウィンドウコントローラーをインスタンス化するための私のアプリケーションは次のとおりです。

self.urlTimerWindowController = [[URLTimerWindowController alloc] init];
[self.urlTimerWindowController showWindow:self];

どんなヒントでも大歓迎です。

4

1 に答える 1

1

テストの問題は、mockWindowControllerurlTimerWindowControllerが同じオブジェクトではないことです。そして、あなたのテストでは、テスト中のクラスselfと同じではありません。selfこの場合、ペン先がロードされなくても問題ありません。

通常、テストするメソッド内でオブジェクトがインスタンス化されている場合、そのオブジェクトをモックすることはできません。1 つの代替方法は、1 つのメソッドでオブジェクトをインスタンス化し、セットアップを完了する別のメソッドに渡すことです。次に、セットアップ方法をテストできます。例えば:

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.urlTimerWindowController = [[URLTimerWindowController alloc] init];
    [self setUpTimerWindow:urlTimerWindowController];
}

-(void)setUpTimerWindow:(URLTimerWindowController *)controller {
    [controller showWindow:self];
}

次に、テストしますsetUpTimerWindow:

-(void)testSetUpTimerWindowShouldShowWindow {
    URLTimerAppDelegate *appDelegate = [[URLTimerAppDelegate alloc] init];

    id mockWindowController = [OCMockObject niceMockForClass:[URLTimerWindowController class]];
    [[mockWindowController expect] showWindow:appDelegate]; // this seems weird. does showWindow really take the app delegate as a parameter?

    [appDelegate setUpTimerWindow:mockWindowController];

    [mockWindowController verify];
    [appDelegate release];
}
于 2011-04-12T17:40:53.553 に答える