このようなものをテストするNSOperationQueue
には、テストで制御する必要があります。
テストしているクラスが と呼ばれているとしMySubject
ます。NSOperationQueue
最初に、テスト用に置き換えて使用できる -- を挿入できるように、リファクタリングする必要があります。したがって、すべての出現を取り除き、[NSOperationQueue mainQueue]
それらをクラス変数に置き換えます。MySubject
のコンストラクターのパラメーターからそのクラス変数を初期化します。MySubject
その結果、 のすべてのインスタンス化を passに変更する必要があります[NSOperationQueue mainQueue]
。
@interface MySubject: NSObject {
NSOperationQueue* operationQueue;
}
@end
@implementation MySubject
-(MySubject*)initWithOperationQueue:(NSOperationQueue*)queue {
if ( self = [super init] ) {
self.operationQueue = [queue retain];
}
return self;
}
-(void)dealloc {
[operationQueue release];
}
-(void)startOperations {
[operationQueue addOperation:...];
[operationQueue addOperation:...];
}
@end
クライアントは次のようになります。
subject = [[MySubject alloc] initWithOperationQueue:[NSOperationQueue mainQueue]];
[subject startOperations];
テストのために、テスト用の単純なキューを作成できます...サブジェクトで使用されるメソッドを実装する必要があります。
@interface MyTestOperationQueue: NSMutableArray {
}
@end
@implementation MySubject
-(void)addOperation:(NSOperation*)operation {
[self addObject:operation];
}
@end
これで、テストは次のようになります。
testQueue = [[MyTestOperationQueue alloc] init];
subject = [[MySubject alloc] initWithOperationQueue:testQueue];
[subject startOperations];
// You may want to have other tests that execute the queue operations
// in a different order
[[testQueue objectAtIndex:0] start];
[[testQueue objectAtIndex:0] waitUntilFinished];
[[testQueue objectAtIndex:1] start];
[[testQueue objectAtIndex:1] waitUntilFinished];
// Verify results
もちろん、この種のテストでは、並行操作が安全に同時に実行できるかどうかを検証することはできませんが、クラスを設計しようとするときに関心のある多くのケースをカバーできます。