OCMock: заглушка @dynamic свойство
Я пытаюсь добавить модульные тесты в существующее приложение iOS, используя, среди прочего OCMock
,
В этом приложении у нас есть набор сущностей CoreData и сгенерированные классы. Эти классы, очевидно, содержат @dynamic
свойства.
Я попытался заглушить одно из этих свойств следующим образом:
self.event = [OCMockObject mockForClass:[ACEvent class]];
[[[self.event stub] andReturn:@"e46e1555-d866-4160-9b42-36d0fb9c29cd"] eventGUID];
Дело в том, что это не работает. Видимо потому что @dynamic
свойство по умолчанию не имеет реализации, и в этом случае для его предоставления используется CoreData. Я заканчиваю с NSError:
-[NSProxy doesNotRecognizeSelector:eventGUID] called!
Я видел другие вопросы, где это было решено путем абстрагирования сущности CoreData за протоколом ( OCMock с проблемой динамических свойств Core Data). Но так как это существующая кодовая база, у меня нет этой опции, так как я не могу позволить себе все реорганизовать.
Кто-нибудь может предложить другое решение для этого?
РЕДАКТИРОВАТЬ: Как примечание, я только что нашел решение, но я боюсь, что это не может работать во всех случаях. Что я сделал, так это предоставил образец пустой реализации этих методов в тестовой цели. Это работает, но я боюсь, что это может сломать другие тесты, которые работают на CoreData. Любое понимание этого?
2 ответа
С OCMock я всегда создаю протокол для каждого управляемого объекта, а затем создаю макеты для этих протоколов, но, как вы сказали, вы не можете этого сделать, поэтому я предлагаю создать поддельный класс с теми же свойствами, которые вы используете в коде, который вы хотите тест (для каждого NSManagedObject
), а затем просто используйте приведение при передаче этих поддельных объектов (либо вы используете OCMock и заглушаете нужные методы, либо просто создаете объект класса поддельных и устанавливаете нужные свойства).
Приведенный выше ответ не удовлетворил меня, потому что я не хотел создавать протокол для этого. Итак, я обнаружил, что есть более простой способ сделать это. Вместо
[[[self.event stub] andReturn:@"e46e1555-d866-4160-9b42-36d0fb9c29cd"] eventGUID];
Просто пиши
[[[self.event stub] andReturn:@"e46e1555-d866-4160-9b42-36d0fb9c29cd"] valueForKey:@"eventGUID"];