Забавена OCMock проверка / Справяне с изчакване в модулни тестове

Тествам реални обаждания на уеб услуги с OCMock.

В момента правя нещо като:

- (void)testWebservice
{
    id mydelegatemock = [OCMockObject mockForProtocol:@protocol(MySUTDelegate)];
    [[mydelegatemock expect] someMethod:[OCMArg any]];

    [SUT sutWithDelegate:mydelegatemock];

    // we need to wait for real result
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];

    [(OCMockObject*)mydelegatemock verify];
}

Работи добре, но това означава, че всеки такъв тест ще отнеме 2 секунди.

Има ли начин да задам изчакване напр. 2 секунди и незабавно извикване до someMethod от mydelegatemock verify и завършване на тестовия случай?


person fabb    schedule 05.09.2011    source източник


Отговори (3)


Правя това с помощта на удобна помощна функция, която намерих на тази връзка:

#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>

@interface TestUtils : NSObject
+ (void)waitForVerifiedMock:(OCMockObject *)mock delay:(NSTimeInterval)delay;
@end

И изпълнението:

#import "TestUtils.h"
@implementation TestUtils

+ (void)waitForVerifiedMock:(OCMockObject *)inMock delay:(NSTimeInterval)inDelay
{
    NSTimeInterval i = 0;
    while (i < inDelay)
    {
        @try
        {
            [inMock verify];
            return;
        }
        @catch (NSException *e) {}
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
        i+=0.5;
    }
    [inMock verify];
}

@end

Това ми позволява да чакам до максимално забавяне (в секунди), без да чакам цялата сума всеки път.

person Tim Dean    schedule 06.09.2011
comment
Може би произхожда от тук?... touchalicious.com /блог/2009/11/5/ - person Max MacLeod; 09.04.2012
comment
Благодаря Макс - това изглежда като източника. Актуализирах оригиналния отговор с връзка към оригинала. - person Tim Dean; 09.04.2012

Бих отделил функционалното тестване на вашите уеб услуги (ако изобщо трябва да го направите) от модулното тестване на вашия клас, който обработва резултата от уеб услугата.

За да тествате единица, трябва да се подиграете на повикването на уеб услугата, като предоставите фиктивен резултат. Тогава вашият тест ще провери дали за този добре дефиниран резултат вашият клас се държи съответно.

Ако също така искате да направите функционално тестване на вашата уеб услуга (да кажем, че тя връща конкретен отговор при дадена заявка), не е нужно да се подигравате на нищо - просто се обадете на услугата и направете твърдения за резултата.

Като разделяте вашите тестове, вие имате по-фин контрол върху тестовите изпълнения. Например, можете да изпълнявате своите бързо изпълняващи се модулни тестове всеки път, когато промените кода, но да изпълнявате своите бавно изпълняващи се функционални тестове всяка нощ, на специален сървър или при необходимост. И когато тестът се повреди, ще разберете дали това е вашият код или нещо не е наред с уеб услугата.

person Christopher Pickslay    schedule 06.09.2011
comment
Вече имам консервирани тестове с незабавни фалшиви връщания от уеб услугата. Този въпрос беше относно интеграционните тестове с реалната уеб услуга. Признавам, че бих могъл да оставя частта за кандидатстване настрана в тях, но това не променя факта, че трябва да изчакам резултата по някакъв начин. И: с готовите резултати не тествам наличието на забавяне между заявката и резултата, тъй като с готовите резултати делегатът за резултат всъщност се извиква преди извикването на заявката да приключи. - person fabb; 06.09.2011

Можете също да превключите към GHUnit, както колега предлага в отговора на този свързан въпрос:

SenTestingKit в Xcode 4: Асинхронно тестване?

Можете да намерите GHUnit тук

https://github.com/gabriel/gh-unit

person thgc    schedule 10.05.2012