From b4e12c3cbf4ea77bf81362826c2d454cb06efccf Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Sun, 17 Nov 2019 17:44:14 +0100 Subject: [PATCH] BAEL-3416 - Mockito and Fluent APIs (#8201) * BAEL-3416 - Mockito and Fluent APIs - stage changes * staging changes * BAEL-3416 - Mockito and Fluent APIs --- .../com/baeldung/mockito/fluentapi/Pizza.java | 102 ++++++++++++++++++ .../mockito/fluentapi/PizzaService.java | 23 ++++ .../fluentapi/PizzaServiceUnitTest.java | 88 +++++++++++++++ .../mockito/fluentapi/PizzaUnitTest.java | 32 ++++++ 4 files changed, 245 insertions(+) create mode 100644 testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/Pizza.java create mode 100644 testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/PizzaService.java create mode 100644 testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaServiceUnitTest.java create mode 100644 testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaUnitTest.java diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/Pizza.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/Pizza.java new file mode 100644 index 0000000000..0a37a2cbbd --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/Pizza.java @@ -0,0 +1,102 @@ +package com.baeldung.mockito.fluentapi; + +import java.util.ArrayList; +import java.util.List; + +public class Pizza { + + public enum PizzaSize { + LARGE, MEDIUM, SMALL; + } + + private String name; + private PizzaSize size; + private List toppings; + private boolean stuffedCrust; + private boolean collect; + private Integer discount; + + private Pizza(PizzaBuilder builder) { + this.name = builder.name; + this.size = builder.size; + this.toppings = builder.toppings; + this.stuffedCrust = builder.stuffedCrust; + this.collect = builder.collect; + this.discount = builder.discount; + } + + public String getName() { + return name; + } + + public PizzaSize getSize() { + return size; + } + + public List getToppings() { + return toppings; + } + + public boolean isStuffedCrust() { + return stuffedCrust; + } + + public boolean isCollecting() { + return collect; + } + + public Integer getDiscount() { + return discount; + } + + public static class PizzaBuilder { + private String name; + private PizzaSize size; + + private List toppings; + private boolean stuffedCrust; + private boolean collect; + private Integer discount = null; + + public PizzaBuilder() { + } + + public PizzaBuilder name(String name) { + this.name = name; + return this; + } + + public PizzaBuilder size(PizzaSize size) { + this.size = size; + return this; + } + + public PizzaBuilder withExtraTopping(String extraTopping) { + if (this.toppings == null) { + toppings = new ArrayList<>(); + } + this.toppings.add(extraTopping); + return this; + } + + public PizzaBuilder withStuffedCrust(boolean stuffedCrust) { + this.stuffedCrust = stuffedCrust; + return this; + } + + public PizzaBuilder willCollect(boolean collect) { + this.collect = collect; + return this; + } + + public PizzaBuilder applyDiscount(Integer discount) { + this.discount = discount; + return this; + } + + public Pizza build() { + return new Pizza(this); + } + } + +} diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/PizzaService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/PizzaService.java new file mode 100644 index 0000000000..0f9d5c6b18 --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/fluentapi/PizzaService.java @@ -0,0 +1,23 @@ +package com.baeldung.mockito.fluentapi; + +import com.baeldung.mockito.fluentapi.Pizza.PizzaSize; + +public class PizzaService { + + private Pizza.PizzaBuilder builder; + + public PizzaService(Pizza.PizzaBuilder builder) { + this.builder = builder; + } + + public Pizza orderHouseSpecial() { + return builder.name("Special") + .size(PizzaSize.LARGE) + .withExtraTopping("Mushrooms") + .withStuffedCrust(true) + .withExtraTopping("Chilli") + .willCollect(true) + .applyDiscount(20) + .build(); + } +} diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaServiceUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaServiceUnitTest.java new file mode 100644 index 0000000000..b5dd10b1d4 --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaServiceUnitTest.java @@ -0,0 +1,88 @@ +package com.baeldung.mockito.fluentapi; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import com.baeldung.mockito.fluentapi.Pizza.PizzaBuilder; +import com.baeldung.mockito.fluentapi.Pizza.PizzaSize; + +public class PizzaServiceUnitTest { + + @Mock + private Pizza expectedPizza; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private PizzaBuilder anotherbuilder; + + @Captor + private ArgumentCaptor stringCaptor; + @Captor + private ArgumentCaptor sizeCaptor; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void givenTraditonalMocking_whenServiceInvoked_thenPizzaIsBuilt() { + PizzaBuilder nameBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + PizzaBuilder sizeBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + PizzaBuilder firstToppingBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + PizzaBuilder secondToppingBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + PizzaBuilder stuffedBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + PizzaBuilder willCollectBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + PizzaBuilder discountBuilder = Mockito.mock(Pizza.PizzaBuilder.class); + + PizzaBuilder builder = Mockito.mock(Pizza.PizzaBuilder.class); + when(builder.name(anyString())).thenReturn(nameBuilder); + when(nameBuilder.size(any(Pizza.PizzaSize.class))).thenReturn(sizeBuilder); + when(sizeBuilder.withExtraTopping(anyString())).thenReturn(firstToppingBuilder); + when(firstToppingBuilder.withStuffedCrust(anyBoolean())).thenReturn(stuffedBuilder); + when(stuffedBuilder.withExtraTopping(anyString())).thenReturn(secondToppingBuilder); + when(secondToppingBuilder.willCollect(anyBoolean())).thenReturn(willCollectBuilder); + when(willCollectBuilder.applyDiscount(anyInt())).thenReturn(discountBuilder); + when(discountBuilder.build()).thenReturn(expectedPizza); + + PizzaService service = new PizzaService(builder); + assertEquals("Expected Pizza", expectedPizza, service.orderHouseSpecial()); + + verify(builder).name(stringCaptor.capture()); + assertEquals("Pizza name: ", "Special", stringCaptor.getValue()); + + verify(nameBuilder).size(sizeCaptor.capture()); + assertEquals("Pizza size: ", PizzaSize.LARGE, sizeCaptor.getValue()); + + } + + @Test + public void givenDeepStubs_whenServiceInvoked_thenPizzaIsBuilt() { + Mockito.when(anotherbuilder.name(anyString()) + .size(any(Pizza.PizzaSize.class)) + .withExtraTopping(anyString()) + .withStuffedCrust(anyBoolean()) + .withExtraTopping(anyString()) + .willCollect(anyBoolean()) + .applyDiscount(anyInt()) + .build()) + .thenReturn(expectedPizza); + + PizzaService service = new PizzaService(anotherbuilder); + assertEquals("Expected Pizza", expectedPizza, service.orderHouseSpecial()); + } + +} diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaUnitTest.java new file mode 100644 index 0000000000..1486cb7f2f --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/fluentapi/PizzaUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.mockito.fluentapi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.baeldung.mockito.fluentapi.Pizza.PizzaSize; + +public class PizzaUnitTest { + + @Test + public void givenFluentPizzaApi_whenBuilt_thenPizzaHasCorrectAttributes() { + Pizza pizza = new Pizza.PizzaBuilder() + .name("Margherita") + .size(PizzaSize.LARGE) + .withExtraTopping("Mushroom") + .withStuffedCrust(false) + .willCollect(true) + .applyDiscount(20) + .build(); + + assertEquals("Pizza name: ", "Margherita", pizza.getName()); + assertEquals("Pizza size: ", PizzaSize.LARGE, pizza.getSize()); + assertEquals("Extra toppings: ", "Mushroom", pizza.getToppings() + .get(0)); + assertFalse("Has stuffed crust: ", pizza.isStuffedCrust()); + assertTrue("Will collect: ", pizza.isCollecting()); + assertEquals("Discounts: ", Integer.valueOf(20), pizza.getDiscount()); + } +}