6

通知を使用するロジックのテストに問題があります。特定の送信を強制することNSNotificationsについて読んだことがありますが、それは私が見ている問題に実際には対処していません。

[SomeObject PerformAsyncOperation]を作成し、NSURLRequestそれ自体を応答デリゲートとして設定します。応答の内容に応じて、SomeObject成功または失敗NSNotificationをデフォルトに投稿しますNSNotificationCenter

私のテストの問題は、PerformAsyncOperation呼び出された後、テストが応答の送信を待たないことです。代わりに、assertを続行します。これは、要求/応答が送信/受信/解析される時間がなかったために失敗します。

コードは次のとおりです。

-(void)testMethod {
    SomeObject *x = [[SomeObject alloc] init];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                        selector:@selector(success:)
                                            name:SomeObjectSuccess
                                          object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                        selector:@selector(failure:)
                                            name:SomeObjectFailure
                                          object:nil];

    operationCompleted = false; // declared in .h

    [x PerformAsyncOperation:@"parameter"];

    STAssertTrue(operationCompleted , @"Operation has completed.");

    [[NSNotificationCenter defaultCenter] removeObserver:self name:SomeObjectSuccess object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:SomeObjectFailure object:nil];

    [x release];
}

-(void) failure:(NSNotification *) notification {
   operationCompleted = true;
   NSLog(@"Received failure message.");
}

-(void) success:(NSNotification *) notification {
   operationCompleted = true;
   NSLog(@"Received success message.");
}

の呼び出しとPerformAsyncOperation空のwhile (!operationCompleted)ループの後にスレッドをスリープさせてみました。どちらも機能しません。スレッドをスリープ状態にしてもアサートは失敗し、whileループは終了しません。success:また、assertをとに移動しようとしましたfailure:が、OCUnitは各メソッドがテストメソッドであることを期待しているため、3つのメソッドすべてをすぐに実行して終了します(NSURLRequest演習の要点である'の応答を待たずに! )。

任意のアイデアや洞察をいただければ幸いです。ありがとう!

4

2 に答える 2

15

あなたが直面している問題は、同期的な通知ではありません。むしろ、非同期操作を開始しているということです。これを繰り返し可能なテストにするには、再同期する必要があります。

NSTimeInterval timeout = 2.0;   // Number of seconds before giving up
NSTimeInterval idle = 0.01;     // Number of seconds to pause within loop
BOOL timedOut = NO;

NSDate *timeoutDate = [[NSDate alloc] initWithTimeIntervalSinceNow:timeout];
while (!timedOut && !operationCompleted)
{
    NSDate *tick = [[NSDate alloc] initWithTimeIntervalSinceNow:idle];
    [[NSRunLoop currentRunLoop] runUntilDate:tick];
    timedOut = ([tick compare:timeoutDate] == NSOrderedDescending);
    [tick release];
}
[timeoutDate release];

この時点を過ぎると、操作が完了したか、テストがタイムアウトしたことがわかります。

于 2011-06-03T05:28:07.390 に答える