2014-01-20 5 views
2

У меня есть класс, который является своего рода оберткой для NSOperationQueue. Он позволяет вставлять сетевые запросы с использованием блоков. В настоящее время запросы выполняются один за другим, но это может быть изменено в будущем.Единичные тесты для NSOperationQueue с maxConcurrentOperationCount

Вот код класса MyRequestsQueue:

@interface MyRequestsQueue() 

@property(nonatomic, strong) NSOperationQueue* queue; 

@end 

@implementation MyRequestsQueue 

-(instancetype)init 
{ 
    self = [super init]; 
    if(!self) { 
     return nil; 
    } 

    self.queue = [[NSOperationQueue new] autorelease]; 
    self.queue.maxConcurrentOperationCount = 1; 

    return self; 
} 

-(void)addRequestBlock:(void (^)())request 
{ 
    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:request]; 
    [self.queue addOperation:operation]; 
} 

@end 

В общем, я знаю, как модульного тестирования асинхронного кода с использованием XCTest. Но теперь я хочу добавить модульный тест для MyRequestsQueue, который проверяет, выполняет ли очередь только одну операцию в то время. Или еще лучше - проверьте, что количество выполняемых в настоящее время операций не превышает maxConcurrentOperationCount. Я попытался заметить operationCount свойство self.queue, но documentation говорит, что я не должен полагаться на него. Как я могу это достичь?

EDIT: Мои тесты используют следующую схему:

@interface MessageRequestQueueTest : XCTestCase 

@property(nonatomic, strong) MessageRequestsQueue* reuqestQueue; 
@property(nonatomic, assign) NSInteger finishedRequestsCounter; 

@end 
// setUp method ommited - simply initializes self.requestQueue 


-(void)testAddedRequestIsExecuted 
{ 
    [self.reuqestQueue.queue setSuspended:YES]; 

    __weak __typeof(self) weakSelf = self; 
    [self.reuqestQueue addRequestBlock:^{ 
     ++weakSelf.finishedRequestsCounter; 
    } withName:kDummyRequestName]; 

    [self.reuqestQueue.queue setSuspended:NO]; 

    WAIT_WHILE(0 == self.finishedRequestsCounter, 0.1); 
    XCTAssertEqual(self.finishedRequestsCounter, 1, @"request should be executed"); 
} 

макрос WAIT_WHILE составляет от AGAsyncTestHelper.

+0

Можете ли вы опубликовать свой модульный метод тестирования? – Greg

+0

Я добавил один из моих модульных методов тестирования. –

ответ

3

Я бы рекомендовал пересмотреть стратегию тестирования.

Но теперь я хочу добавить модульный тест для MyRequestsQueue, который проверяет, выполняет ли очередь только одну операцию в то время. Или еще лучше - проверьте, что количество выполняемых операций не превышает maxConcurrentOperationCount.

Оба эти испытания будут тестировать реализацию Apple NSOperationQueue, которая не принесет вам ничего. Вы не хотите быть модульным кодом, который у вас нет, и в целом вы должны предположить, что Apple правильно проверила свой собственный код. Если бы NSOperationQueue выполнял больше параллельных операций, чем следовало бы, у Apple была бы большая проблема!

Вместо этого я просто проверил, что после того, как он был инициализирован, ваш MyRequestsQueue установил правильный maxConcurrentOperationCount на своем NSOperationQueue.

+1

тестирование maxConcurrentOperationCount - это самое простое решение, которое работает :) Возможно, я переусердствовал. –

+1

Я думаю, что важно попробовать и взвесить усилия по тестированию определенной функциональности, а не насколько вероятно, что это вызовет проблему, и насколько вы выиграете от ее тестирования. Вы должны быть в состоянии с уверенностью предположить, что 'NSOperationQueue' будет уважать установленный вами' maxConcurrentOperationCount', поэтому вам не пригодится попробовать и проверить это - просто убедитесь, что вы правильно установили значение :) –

1

Помогите? проверьте недвижимость count.

@interface MyRequestsQueue() 

@property(nonatomic, strong) NSOperationQueue* queue; 
@property(assign) NSUInteger count ; 

@end 

@implementation MyRequestsQueue 

-(instancetype)init 
{ 
    self = [super init]; 
    if(!self) { 
     return nil; 
    } 

    self.queue = [[NSOperationQueue new] autorelease]; 
    self.queue.maxConcurrentOperationCount = 1; 

    return self; 
} 

-(void)addRequestBlock:(void (^)())request 
{ 
    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:^{ 
     ++self.count ; 
     request() ; 
     --self.count ; 
    }] ; 
    [self.queue addOperation:operation]; 
} 

@end 
+0

Хорошая идея. Тем не менее, я не знаю, как проверить, что значение self.count никогда не превышает 1. –

Смежные вопросы