Класс класса OCMock не работает должным образом - PullRequest
0 голосов
/ 15 января 2019

У меня есть следующая UIImage категория:

@implementation UIImage (Exception)

+ (nullable UIImage *)imageCanThrowWithData:(NSData *)data error:(NSError **)errorPtr
{
    UIImage *image = nil;

    @try {
        image = [self imageWithData:data];
    } @catch (id exception) {
        *errorPtr = [NSError errorWithDomain:@"mydomain" code:0 userInfo:nil];
    }

    return image;
}

@end

А потом я пытаюсь проверить это с помощью OCMock:

выдержка из настройки ...

beforeEach(^{
        NSString* labelPath = [[NSBundle mainBundle] pathForResource:@"image" ofType:@"jpg"];
        imageData = [NSData dataWithContentsOfFile:labelPath];
        image = [UIImage imageWithData:imageData];
    });


it(@"should return the image if no exception is thrown", ^{
        id mock = OCMStrictClassMock([UIImage class]);

        NSError *error = nil;

        OCMStub([mock imageWithData:OCMOCK_ANY]).andReturn(image);

        OCMStub([mock imageMightThrowWithData:imageData error:&error]).andReturn([UIImage imageMightThrowWithData:imageData error:&error]);

        UIImage* resultImage = [[mock expect] imageMightThrowWithData:imageData error:&error];
        expect(resultImage).toNot(beNil());
        expect(error).to(beNil());

        [mock stopMocking];
    });

Почему resultImage это nil. Примечания:
Я не эксперт по OCMock, поэтому я могу делать что-то наивное.
UIImage imageWithData может выдать исключение в случае, если вы имеете дело с внешним хранилищем основных данных.

Ответы [ 2 ]

0 голосов
/ 12 марта 2019

Обычно вы не создаете заглушку или ожидание для метода, который вы пытаетесь протестировать.

Если я правильно понимаю цель вашего модульного теста, то есть проверьте, что возвращаемое значение не равно нулю, если нет исключений, вы можете выполнить следующие шаги:

  1. Stub +[UIImage imageWithData:] для возврата UIImage объекта.
  2. Вызовите +[UIImage imageCanThrowWithData: error:] и сохраните возвращенное значение в локальной переменной.
  3. Убедитесь, что возвращаемое значение не равно нулю.
id imageMock = OCMClassMock([UIImage class]);
OCMStub([imageMock imageWithData:OCMOCK_ANY]).andReturn(imageMock);
NSData *data = OCMClassMock([NSData class]);
UIImage *result = [UIImage imageCanThrowWithData:data error:nil];
XCTAssertNotNil(result);

Примечание: Хорошей практикой является использование только одного утверждения на тест, поэтому я бы предложил создать отдельное утверждение, чтобы проверить, что ошибка равна нулю, когда не выдается никаких исключений.

0 голосов
/ 16 января 2019

Вы издеваетесь над методом + imageMightThrowWithData: error:, но затем пытаетесь вызвать проверяемый метод как часть проверяемой реализации. Я не уверен, каков будет результат, но меня не удивит, если это просто не получится и вернет ноль. Вы используете OCMStrictClassMock, что означает, что вы больше не можете вызывать какие-либо методы класса в UIImage, включая ваши собственные.

Однако, поскольку imageData уже предоставляется в качестве аргумента, вам вообще не нужно его высмеивать - просто передайте аргумент, с которым вы хотите проверить. На самом деле, вам не нужно высмеивать + imageWithData: либо. Просто передайте imageData, который у вас уже есть. Я мог бы видеть mocking + imageWithData: бросать с нестрогой насмешкой, чтобы протестировать этот случай (если вы не можете легко получить NSData, который вначале вызовет метод Apple), но для этого тест Я не вижу необходимости использовать OCMock вообще. Так что просто удалите OCMStrictClassMock и два вызова OCMStub, и я думаю, что это должно работать.

Если вы хотите смоделировать метод imageWithData: так, чтобы он возвращался быстрее, я думаю, это должно сработать, но используйте OCMClassMock, а не строгий, так что вы все еще можете протестировать свой собственный метод класса, а затем не OCMStub метод, который вы пытаетесь проверить.

...