Mockito как да създадете макет и
Създаване на макет обект започва с призив да се подиграват (клас
- typeToMock - клас вид на бъдещата mock'a
- mock'a настройки - настройки
Типичен разговор, за да създадете мока е както следва:
В тази конфигурация mock'a инициализира по подразбиране се използва Mockito.withSettings на метода (). изпълнение, която връща интерфейс за настройки. Настройки на А клас интерфейс подиграват обект две - org.mockito.MockSettings и org.mockito.mock.MockCreationSettings. Първият определя начините на mock'ov настройка на параметрите, втората определя интерфейс за достъп до тези параметри, без възможност за промяна. Съответно стойностите на влизането в обекта, произведен през първата интерфейс, както и всички други класове работят с параметрите чрез втория интерфейс, че нищо в него не е случайно променя. Настройките могат да бъдат настроени ръчно, когато създавате макет обект. По-конкретно, можете да посочите всяко име mock'a да тестват изпълнение трупи са станали по-ясни.
При създаването на mock'a, цялата му методи stubb'iruyutsya. резултати Метод кол определят Отговор обект. За важните методи за изпитване и да поискаме отговор обект ръчно чрез Mockito.when дизайн (Matcher) .thenAnswer (Отговор). За други обекти, наречена Отговор по подразбиране. Специфичното приложение се определя и в настройките за реакция mock'a и той може да бъде заменен. Настройката по подразбиране се използва org.mockito.internal.stubbing.defaultanswers.GloballyConfiguredAnswer. Този отговор, от своя страна, е делегирал изпълнението на отговор на заявката, която се определя в глобалната конфигурация обект, който е бил разглеждан в статията Mockito: Обработка пояснения. В конфигурацията, както са определени org.mockito.internal.stubbing.defaultanswers.ReturnsEmptyValues изпълнение. който връща нулеви стойности за различни видове обекти.
В допълнение GloballyConfiguredAnswer. в Mockito. реализирани няколко реализации на отговорите, връзките към тези обекти се съхраняват в Enum'e org.mockito.Answers. Също Mockito по-достъпна и вътрешен изпълнение на отговорите, като ReturnsEmptyValues и ReturnsMoreEmptyValues. поискване Последно делегати ReturnsEmptyValues и допълва логиката на определяне на няколко вида данни. Фактът, че ReturnsEmptyValues връща нула за всички обекти, с изключение на някои реализации на колекции от примитиви и техните опаковки. В един момент разработчиците са решили да подкрепят повече струни и масиви, но като човек, който е вероятно да имат време да пишат тестове с оглед на спецификата, а след това просто да се актуализира съществуващото изпълнението не е достатъчно. Необходимо е да се създаде нов вид отговор ReturnsMoreEmptyValues. Нов отговор в момента се използва при прилагането на отговор ReturnsSmartNulls. който, вместо да се опитва да създаде нула и да се върнете mock'realizatsiyu този тип.
Има и друго вътрешно изпълнение на отговорите, но няма нищо по-интересно. Възможно е също така да се уточни в настройките на обектите - студентите, които ще бъдат уведомени по време на извикване на метода. Тези обекти прилагат org.mockito.MockSettings.InvocationListener интерфейс.
Наред с другите неща, класа на основни настройки има метод за автотеста, който приема аргумента на класа на обекта, който се предвижда да се създаде макет, и проверява възможността да се създават mock'a с тези настройки. В случай на успешно потвърждаване, нов екземпляр от настройките на обектите, които се определят наименованието на обекта и преработени настройките mock'a определени по-рано. име мока обект интерфейс org.mockito.internal.util.MockName използва за съхраняване на името на мока и за извършване на някои операции по обработката на име Мока.
Основната цел на системата, вие създавате един обект, който реализира интерфейс org.mockito.plugins.MockMaker. но директно с този обект е само утилитарен клас org.mockito.internal.util.MockUtil. Това е метод, клас, наречен в MockUtil createMock MockitoCore # макет. Първият обект е създаден с org.mockito.invocation.MockHandler на интерфейса. който приема повикването stabbirovannyh методи в макет обекта. Обекти прехващачи са фабрично org.mockito.internal.handler.MockHandlerFactory. Създава внедряването на основен org.mockito.internal.handler.MockHandlerImpl манипулатор и различни завои wrapper'ami (обвивка образец) за закрепване на допълнителна функционалност. В този момент, както следва обвивка:
- org.mockito.internal.handler.NullResultGuardian нули за предотвратяване на върнатите стойности на методите, които връщат примитивните видове или техните опаковки.
- org.mockito.internal.handler.MockHandlerFactory уведомява слушателите обявени в настройките на викането на метода.
Следваща метод се нарича MockMaker # createMock. където настройки се прехвърлят и MockHandler. MockMaker'a обект се създава в областта на статичен клас MockUtil използване ClassPathLoader. които са били използвани, за да изтеглите потребителски конфигурация клас изпълнение. метод SlassPathLoader # getMockMaker връща предварително заредени MockMaker'a изпълнение. Както и с конфигурацията на обект, е възможно да използвам моя MockMaker'a изпълнение. но зареждането на принципа е различна:
С ClassLoader'a изтеглен файл с името на класа премина на аргумента на обслужване. В момента, тъй като услугата се използва MockMaker клас. File се търси в папката с име "mockito-разширение". Файлът съдържа пълните имена на класовете - клас по линията. Освен това, тези класове са заредени и техните обекти. Въпреки възможността за качване на множество MockMaker'ov. Тя ще се прилага само за първия намерен. Ако класът потребител все още не е налице, по подразбиране се стартира MockMaker org.mockito.internal.creation.CglibMockMaker.
Създаване на прокси класове и макет обект и в действителност те са по подразбиране при условие CGLib библиотека. Източници на библиотеката включени в проекта, така че да не се занимавам с версията на проекта и преопаковане източника. Разбира се, Maven ще улесни задачата и структурата на проекта ще стане по-ясно, но това, което е направено е направено. На разработчиците няма да променят изходния код и като цяло е забранено. CGLib - библиотека, която ви позволява да създавате, разширяване на класове и интерфейси в runtime'e.
Вътре MockMaker "манипулатор повикване stabbirovannyh методи - MockHandler превръща в MethodInterceptorFilter клас. MethodInterceptor реализира интерфейса. която е част от CGLib библиотека.
Странното е, че логиката на създаване на обекти, използващи CGLib замъглено и е описан в определен утилитарен org.mockito.internal.creation.jmock.ClassImposterizer клас. който вече е бил използван в настройките проверка mock'obekta. Този клас е заимстван от jMock на библиотеката.
#Thanks до jMock момчета за този удобен клас тайна, че всички cglib магия.
Този клас се въвежда хетерогенност в Mockito. това е много грозно. Например, за да се създаде клас случаи, използвани objenesis библиотека. В Mockito като тази процедура се извършва директно, като се използва отражение.
На първо място определя видимостта на дизайнери, което създава клас за Mock обект. Ние вече сме преминали. Решени методи двойка отражение. На следващо място, създаване на прокси клас обект. Тази работа се извършва с помощта на CGLib клас Enhancer. Този клас конструира класа за бъдещо пълномощник в параметрите, които сме прехвърлени.
Изпуснах някои точки на sekyurnostyu класове и управление на обработка на изключения. Те са незначителни.
За да започнете да се реши проблема с бъг CGLib. който отказва да се справят с клас обект. защото някъде, вероятно свързана с родителския клас. Т.е. ако видът на макет обект - обект. ние създаваме празен обект ClassWithSuperclassToWorkAroundCglibBug. който по-нататъшна работа. След това създайте Enhancer'a обект. и той почина classloader'y бъдещи класове mock'ov увити във вътрешната CGLib класа да работи с всички намерени classloader'ami като такъв. Клас на, наред с другото, ще реализира интерфейса фабрика. който определя методите на метода инсталация манипулатор повиквания и инстанциирането на тези обекти. Това е вътрешна функция CGLib. Допълнителни точки Enhancer'u видове класове и интерфейси, че ще наследят и видове метод процесори прехващачи клас. В този случай, стандартните класове MethodInterceptor. който ви позволява да дефинирате посредници и NoOp. който предава методите за управление на обект директно - трябва да шпионира mokov.
Следващата стъпка е да се създаде прокси обект:
Както може да се види, objensis значително опростява създаването на обекти. Разработчиците явно не са достигнали ръцете да пренапише кода помощта на тази библиотека. Както със събития, за да уточнят създадена по-рано InternalMockHandler и празен изпълнение NoOp интерфейс.
Сега остава само да се информират всички компоненти на събитието създаване мока:
и го връща на теста за класна стая.
Бих искала да отбележа, че много от кода твърдо кодиране. Има много места, където методът отнема параметри на общ интерфейс и предмет в метода се проверява за съответствие с определен тип, който реализира този интерфейс:
Но си струва да отдаде почит на разработчиците за грижа за потребителите - разширяване на проекта, те не се опита да промени старата част на API. Това е срамота, че би било да се пренапише един куп тестове по време на прехода към новата версия Mockito.