1. Въведение
Mockito е популярна подигравателна рамка за Java. С него е лесно да създавате фиктивни обекти, да конфигурирате фалшиво поведение, да улавяте аргументи на метода и да проверявате взаимодействието с макети.
Сега ще се съсредоточим върху уточняване на фалшиво поведение. Имаме два начина да направим това: синтаксисът когато (). ThenDoSomething () и doSomething (). When () .
В този кратък урок ще видим защо имаме и двамата.
2. когато () Метод
Нека разгледаме следния интерфейс на служителя :
interface Employee { String greet(); void work(DayOfWeek day); }
В нашите тестове използваме макет на този интерфейс. Да приемем, че искаме да конфигурираме метода на mock's greet () да връща низа “Hello” . Това е лесно да се направи, като се използва методът на Mockito when () :
@Test void givenNonVoidMethod_callingWhen_shouldConfigureBehavior() { // given when(employee.greet()).thenReturn("Hello"); // when String greeting = employee.greet(); // then assertThat(greeting, is("Hello")); }
Какво става? Обектът на служителя е макет. Когато извикаме някой от методите му, Mockito регистрира това обаждане. С извикването на метода when () Mockito знае, че това извикване не е било взаимодействие от бизнес логиката. Това беше изявление, че искаме да присвоим някакво поведение на фалшивия обект. След това с един от методите thenXxx () указваме очакваното поведение.
До този момент това е добро старо подигравка. По същия начин искаме да конфигурираме метода work () да изхвърля изключение, когато го извикаме с аргумент от неделя:
@Test void givenVoidMethod_callingWhen_wontCompile() { // given when(employee.work(DayOfWeek.SUNDAY)).thenThrow(new IAmOnHolidayException()); // when Executable workCall = () -> employee.work(DayOfWeek.SUNDAY); // then assertThrows(IAmOnHolidayException.class, workCall); }
За съжаление този код няма да се компилира, тъй като в извикването work (worker.work (…) ) методът work () има тип void return; следователно не можем да го увием в друго извикване на метод. Означава ли това, че не можем да се подиграваме с методите за нищожност? Разбира се, че можем. doXxx методи за спасяване!
3. Методи на doXxx ()
Нека да видим как можем да конфигурираме хвърлянето на изключения с метода doThrow () :
@Test void givenVoidMethod_callingDoThrow_shouldConfigureBehavior() { // given doThrow(new IAmOnHolidayException()).when(employee).work(DayOfWeek.SUNDAY); // when Executable workCall = () -> employee.work(DayOfWeek.SUNDAY); // then assertThrows(IAmOnHolidayException.class, workCall); }
Този синтаксис е малко по-различен от предишния: ние не се опитваме да обгърнем извикване на void метод в друго извикване на метод. Следователно този код се компилира.
Да видим какво се случи току-що. Първо, заявихме, че искаме да направим изключение. След това извикахме метода when () и предадохме фиктивния обект. След това посочихме кое поведение на взаимодействие искаме да конфигурираме.
Имайте предвид, че това не е същото когато () метод, който използвахме преди. Също така имайте предвид, че ние приковахме фиктивното взаимодействие след извикването на when (). Междувременно го дефинирахме в скобите с първия синтаксис.
Защо имаме първото, когато (). ThenXxx () , когато не е в състояние да изпълнява толкова често срещана задача, като конфигуриране на void извикване? Той има множество предимства пред синтаксиса doXxx (). When () .
Първо, по-логично е разработчиците да пишат и четат изявления като „когато някакво взаимодействие, тогава направете нещо“, отколкото „направете нещо, когато някакво взаимодействие“.
Второ, можем да добавим множество поведения към едно и също взаимодействие с верига. Това е така, защото когато () връща екземпляр на класа OngoingStubbing , който методите thenXxx () връщат същия тип.
От друга страна, методите doXxx () връщат екземпляр Stubber , а Stubber.when (T mock) връща T , така че можем да посочим какъв вид извикване на метод искаме да конфигурираме. Но T е част от нашето приложение, например Служител в нашите кодови фрагменти. Но T няма да върне клас Mockito, така че няма да можем да добавим множество поведения с верига.
4. BDDMockito
BDDMockito използва алтернативен синтаксис на тези, които разгледахме. Това е доста просто: в нашите фиктивни конфигурации трябва да заменим ключовата дума „ когато“ на „ дадена “ и ключовата дума „ направете “ на „ ще “. Освен това нашият код остава същият:
@Test void givenNonVoidMethod_callingGiven_shouldConfigureBehavior() { // given given(employee.greet()).willReturn("Hello"); // when String greeting = employee.greet(); // then assertThat(greeting, is("Hello")); } @Test void givenVoidMethod_callingWillThrow_shouldConfigureBehavior() { // given willThrow(new IAmOnHolidayException()).given(employee).work(DayOfWeek.SUNDAY); // when Executable workCall = () -> employee.work(DayOfWeek.SUNDAY); // then assertThrows(IAmOnHolidayException.class, workCall); }
5. Заключение
Видяхме предимствата и недостатъците на конфигурирането на фалшив обект по начин when (). ThenXxx () или doXxx (). When () . Също така видяхме как работят тези синтаксиси и защо имаме и двете.
Както обикновено, примерите са достъпни в GitHub.