そう思って、雑に実装をしてみました。

[[foo shouldEventually] receive:@selector(bar)]はKiwiの構文で、
一定時間以内にbarというメソッドが呼ばれないとテスト失敗とするものです。

具体的には以下のようなプログラムでfoobarが呼ばれるか確認するテストに使えます。

- (void)someMethod:(id)foo
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        ...

        [foo bar];
    });
}

KiwiのshouldEventuallyKWProbePollerが0.1秒ごとにNSRunLoopを回し、
KWAsyncMatcherProbeisSatisfiedYESになるまで回し続けるという実装をしています。

// KWProbePoller

- (BOOL)check:(id<KWProbe>)probe;
{
  KWTimeout *timeout = [[KWTimeout alloc] initWithTimeout:timeoutInterval];

  while (![probe isSatisfied]) {
    if ([timeout hasTimedOut]) {
      [timeout release];
      return NO;
    }
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:delayInterval]];
    [probe sample];
  }
  [timeout release];

  return YES;
}

OCMockreceive:に相当するものはexpect/verifyなので、これらを使って同じことをします。

OCMockObjectexpectationsというNSArrayがあり、expectするとOCMockRecorderを追加し、
メソッドが呼ばれるとOCMockRecorderexpectationsから外すという処理をします。
そして、verify時にexpectationsが残っているとテストを失敗させる仕組みになっています。

// OCMockObject

- (void)verify
{
	if([expectations count] == 1)
	{
		[NSException raise:NSInternalInconsistencyException format:@"%@: expected method was not invoked: %@", 
			[self description], [[expectations objectAtIndex:0] description]];
	}
	if([expectations count] > 0)
	{
		[NSException raise:NSInternalInconsistencyException format:@"%@ : %ld expected methods were not invoked: %@", 
			[self description], [expectations count], [self _recorderDescriptions:YES]];
	}
	if([exceptions count] > 0)
	{
		[[exceptions objectAtIndex:0] raise];
	}
}

なので、expectationsが変わるまでNSRunLoopを回すというverifyの代替メソッドを用意すれば、
OCMockらしく[[foo shouldEventually] receive:@selector(bar)]に相当するものが実装できます。

以下がその実装です。

@implementation OCMockObject (Lazy)

- (void)verifyLazily
{
    [self verifyLazilyWithTimeout:1.0];
}

- (void)verifyLazilyWithTimeout:(NSTimeInterval)timeout
{
    NSTimeInterval interval = 0.1;
    NSDate *startedDate = [NSDate date];
    BOOL shouldContinue = YES;
    
    while (shouldContinue) {
        @autoreleasepool {
            shouldContinue = [[NSDate date] timeIntervalSinceDate:startedDate] < timeout;
            if (!shouldContinue || [self->expectations count] == 0) {
                [self verify];
            }
            
            NSDate *date = [NSDate dateWithTimeIntervalSinceNow:interval];
            [[NSRunLoop currentRunLoop] runUntilDate:date];
        }
    }
}

@end

これを利用したテストケースは以下のように書くことができます。

- (void)testFooInvokesBarOnSomeMethod
{
    id fooMock = [OCMockObject mockForClass:[Foo class]];
    [[fooMock expect] bar];
    
    [testObject someMethod:fooMock];
    STAssertNoThrow([fooMock verifyLazily], @"foo did not invoke bar.");
}

勢い余ってやってみたという感じなのですが、もっと良い方法があれば知りたいです。