Класс класса OCMock не работает должным образом

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

@implementation UIImage (Исключение)

+ (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 может выдать исключение в случае, если вы имеете дело с внешним хранилищем основных данных.

1 ответ

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

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

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

You don't normally create a stub or an expectation for the method that you're trying to test.

If I understand the purpose of your unit test correctly, i.e. check that the returned value is not nil when there are no exceptions, you could follow these steps:

  1. Stub +[UIImage imageWithData:] to return a UIImage object.
  2. Call +[UIImage imageCanThrowWithData: error:] and save the returned value in a local variable.
  3. Check that the returned value is not nil.
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);

Note: It's good practice to have only one assertion per test, so I would suggest creating a separate one to check that the error is nil when no exceptions are thrown.

Другие вопросы по тегам