Класс класса 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:
- Stub
+[UIImage imageWithData:]
to return aUIImage
object. - Call
+[UIImage imageCanThrowWithData: error:]
and save the returned value in a local variable. - 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.