Разлика между методите когато () и doXxx () в Mockito

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.