diff --git a/.m2/settings.xml b/.m2/settings.xml new file mode 100644 index 0000000..510e0ba --- /dev/null +++ b/.m2/settings.xml @@ -0,0 +1,18 @@ + + + org.sonarsource.scanner.maven + + + + sonar + + true + + + + http://localhost:9000 + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 4cfab93..5ed8d5e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,72 @@ # Dépôt des sources JAVA pour cours CICD -Sources accompagnant le cours "Continuous Integration, Continuous Delivery" +1/ Création des configurations par profil + +Port: + +DEV: 8090 (par défaut) +UAT : 8091 +PROD : 8092 + +Avec Spring-boot, les propriétés propres au profil se définissent dans des fichiers: application-.yml + +application-uat.yml +application-prod.yml + + +Démarrer l'application en CMD et démontrer qu'en fonction de l'environnement défini, on démarre sur un port différent: + +mvn clean package -DskipTests + +java -jar -Dspring.profiles.active=dev|uat|prod target\calculator.jar + + +2/ Déploiement manuel pour chaque environnement + + +a/ Configuration de Docker + +Pas de serveurs donc nous allons utiliser des containers (Pas des machines virtuelles) + +Overview Dockerfile + +Configuration de l'image Docker via le Dockerfile + + +Externaliser entrypoint.sh afin d'avoir plus de maléabilité + + +Lancer l'application pour chaque environnement + + + +Sur la branche actuelle: m1ch3 + +mvn sonar:sonar -s .m2/settings.xml -Dsonar.login= ==> est ce OK ? + +Empaquetter l'application a containeuriser + +docker build -t calculator-demo:1.0.0 . + +docker run --name calculator-demo --env SPRING_ACTIVE_PROFILES=dev calculator-demo:dev + + + +Si tout est OK, on fait une fusion avec la branche ready et l'on contruit/exécute l'image pour l'uat + +mvn sonar:sonar -s .m2/settings.xml -Dsonar.login= ==> est ce OK ? + +docker build -t calculator-demo:uat + +docker run --name calculator-demo --env SPRING_ACTIVE_PROFILES=uat calculator-demo:uat + + + + +si tout est OK, on fait une fusion avec main et l'on construit exécute l'image pour la PROD + +mvn sonar:sonar -s .m2/settings.xml -Dsonar.login= ==> est ce OK ? + +docker build -t calculator-demo:prod + +docker run --name calculator-prod --env SPRING_ACTIVE_PROFILES=prod calculator-demo:prod diff --git a/pom.xml b/pom.xml index 0c27268..cc8ec87 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,16 @@ javax.inject 1 + + org.seleniumhq.selenium + selenium-java + test + + + io.github.bonigarcia + webdrivermanager + 3.7.1 + calculator @@ -92,6 +102,26 @@ + + org.jacoco + jacoco-maven-plugin + 0.8.2 + + + + prepare-agent + + + + + report + test + + report + + + + \ No newline at end of file diff --git a/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java b/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java index 6492e44..afe011e 100644 --- a/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java +++ b/src/main/java/tech/zerofiltre/testing/calcul/domain/Calculator.java @@ -4,10 +4,14 @@ import java.util.Set; import javax.inject.Named; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Named public class Calculator { + Logger logger = LoggerFactory.getLogger(Calculator.class); + public int add(int a, int b) { return a + b; } @@ -54,12 +58,12 @@ public void longCalculation() { try { Thread.sleep(500); } catch (final InterruptedException e) { - e.printStackTrace(); + logger.debug("Thread has been interrupted", e); } } public Set digitsSet(int number) { - final Set integers = new HashSet(); + final Set integers = new HashSet<>(); final String numberString = String.valueOf(number); for (int i = 0; i < numberString.length(); i++) { diff --git a/src/main/resources/templates/calculator.html b/src/main/resources/templates/calculator.html index 9174951..277575c 100644 --- a/src/main/resources/templates/calculator.html +++ b/src/main/resources/templates/calculator.html @@ -28,10 +28,10 @@

- +
- @@ -39,12 +39,12 @@

- +
- +
diff --git a/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java b/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java index 382bbe7..b81b853 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/controller/CalculatorControllerSIT.java @@ -22,7 +22,7 @@ @WebMvcTest(controllers = { CalculatorController.class, CalculatorService.class }) @ExtendWith(SpringExtension.class) -public class CalculatorControllerSIT { +class CalculatorControllerSIT { @Inject private MockMvc mockMvc; @@ -34,7 +34,7 @@ public class CalculatorControllerSIT { private Calculator calculator; @Test - public void givenACalculatorApp_whenRequestToAdd_thenSolutionIsShown() throws Exception { + void givenACalculatorApp_whenRequestToAdd_thenSolutionIsShown() throws Exception { // GIVEN when(calculator.add(2, 3)).thenReturn(5); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java index 7ef7a90..c72844e 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/CalculatorTest.java @@ -27,7 +27,7 @@ import org.junit.jupiter.params.provider.ValueSource; @ExtendWith(LoggingExtension.class) -public class CalculatorTest { +class CalculatorTest { private static Instant startedAt; @@ -40,25 +40,25 @@ public void setLogger(Logger logger) { } @BeforeEach - public void initCalculator() { + void initCalculator() { logger.info("Appel avant chaque test"); calculatorUnderTest = new Calculator(); } @AfterEach - public void undefCalculator() { + void undefCalculator() { logger.info("Appel après chaque test"); calculatorUnderTest = null; } @BeforeAll - public static void initStartingTime() { + static void initStartingTime() { System.out.println("Appel avant tous les tests"); startedAt = Instant.now(); } @AfterAll - public static void showTestDuration() { + static void showTestDuration() { System.out.println("Appel après tous les tests"); final Instant endedAt = Instant.now(); final long duration = Duration.between(startedAt, endedAt).toMillis(); @@ -66,7 +66,7 @@ public static void showTestDuration() { } @Test - public void testAddTwoPositiveNumbers() { + void testAddTwoPositiveNumbers() { // Arrange final int a = 2; final int b = 3; @@ -80,7 +80,7 @@ public void testAddTwoPositiveNumbers() { } @Test - public void multiply_shouldReturnTheProduct_ofTwoIntegers() { + void multiply_shouldReturnTheProduct_ofTwoIntegers() { // Arrange final int a = 42; final int b = 11; @@ -94,7 +94,7 @@ public void multiply_shouldReturnTheProduct_ofTwoIntegers() { @ParameterizedTest(name = "{0} x 0 doit être égal à 0") @ValueSource(ints = { 1, 2, 42, 1011, 5089 }) - public void multiply_shouldReturnZero_ofZeroWithMultipleIntegers(int arg) { + void multiply_shouldReturnZero_ofZeroWithMultipleIntegers(int arg) { // Arrange -- Tout est prêt ! // Act -- Multiplier par zéro @@ -106,7 +106,7 @@ public void multiply_shouldReturnZero_ofZeroWithMultipleIntegers(int arg) { @ParameterizedTest(name = "{0} + {1} doit être égal à {2}") @CsvSource({ "1,1,2", "2,3,5", "42,57,99" }) - public void add_shouldReturnTheSum_ofMultipleIntegers(int arg1, int arg2, int expectResult) { + void add_shouldReturnTheSum_ofMultipleIntegers(int arg1, int arg2, int expectResult) { // Arrange -- Tout est prêt ! // Act @@ -118,7 +118,7 @@ public void add_shouldReturnTheSum_ofMultipleIntegers(int arg1, int arg2, int ex @Timeout(1) @Test - public void longCalcul_shouldComputeInLessThan1Second() { + void longCalcul_shouldComputeInLessThan1Second() { // Arrange // Act @@ -129,7 +129,7 @@ public void longCalcul_shouldComputeInLessThan1Second() { } @Test - public void listDigits_shouldReturnsTheListOfDigits_ofPositiveInteger() { + void listDigits_shouldReturnsTheListOfDigits_ofPositiveInteger() { // GIVEN final int number = 95897; @@ -143,14 +143,14 @@ public void listDigits_shouldReturnsTheListOfDigits_ofPositiveInteger() { } @Test - public void listDigits_shouldReturnsTheListOfDigits_ofNegativeInteger() { + void listDigits_shouldReturnsTheListOfDigits_ofNegativeInteger() { final int number = -124432; final Set actualDigits = calculatorUnderTest.digitsSet(number); assertThat(actualDigits).containsExactlyInAnyOrder(1, 2, 3, 4); } @Test - public void listDigits_shouldReturnsTheListOfZero_ofZero() { + void listDigits_shouldReturnsTheListOfZero_ofZero() { final int number = 0; final Set actualDigits = calculatorUnderTest.digitsSet(number); assertThat(actualDigits).containsExactly(0); @@ -158,7 +158,7 @@ public void listDigits_shouldReturnsTheListOfZero_ofZero() { @Disabled("Stoppé car cela échoue tous les mardis") @Test - public void testDate() { + void testDate() { // GIVEN final LocalDateTime dateTime = LocalDateTime.now(); @@ -169,7 +169,7 @@ public void testDate() { } @Test - public void fact12_shouldReturnsTheCorrectAnswer() { + void fact12_shouldReturnsTheCorrectAnswer() { // GIVEN final int number = 12; @@ -182,7 +182,7 @@ public void fact12_shouldReturnsTheCorrectAnswer() { } @Test - public void digitsSetOfFact12_shouldReturnsTheCorrectAnswser() { + void digitsSetOfFact12_shouldReturnsTheCorrectAnswser() { // GIVEN final int cacheFactorial = 479001600; @@ -194,7 +194,7 @@ public void digitsSetOfFact12_shouldReturnsTheCorrectAnswser() { } @Test - public void multiplyAndDivide_shouldBeIdentity() { + void multiplyAndDivide_shouldBeIdentity() { // GIVEN final Random r = new Random(); final int a = 1 + r.nextInt(100); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java index 1fb80e8..188e0a8 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/ConversionCalculatorTest.java @@ -12,7 +12,7 @@ @Tag("ConversionTests") @DisplayName("Réussir à convertir entre différentes unités.") -public class ConversionCalculatorTest { + class ConversionCalculatorTest { private ConversionCalculator calculatorUnderTest = new ConversionCalculator(); @@ -22,14 +22,14 @@ public class ConversionCalculatorTest { class TemperatureTests { @Test @DisplayName("Soit une T° à 0°C, lorsque l'on convertit en °F, alors on obtient 32°F.") - public void celsiusToFahrenheit_returnsAFahrenheitTempurature_whenCelsiusIsZero() { + void celsiusToFahrenheit_returnsAFahrenheitTempurature_whenCelsiusIsZero() { Double actualFahrenheit = calculatorUnderTest.celsiusToFahrenheit(0.0); assertThat(actualFahrenheit).isCloseTo(32.0, withinPercentage(0.01)); } @Test @DisplayName("Soit une T° à 32°F, lorsque l'on convertit en °C, alors on obtient 0°C.") - public void fahrenheitToCelsius_returnsZeroCelciusTempurature_whenThirtyTwo() { + void fahrenheitToCelsius_returnsZeroCelciusTempurature_whenThirtyTwo() { Double actualCelsius = calculatorUnderTest.fahrenheitToCelsius(32.0); assertThat(actualCelsius).isCloseTo(0.0, withinPercentage(0.01)); } @@ -37,14 +37,14 @@ public void fahrenheitToCelsius_returnsZeroCelciusTempurature_whenThirtyTwo() { @Test @DisplayName("Soit un volume de 3.78541 litres, en gallons, on obtient 1 gallon.") - public void litresToGallons_returnsOneGallon_whenConvertingTheEquivalentLitres() { + void litresToGallons_returnsOneGallon_whenConvertingTheEquivalentLitres() { Double actualLitres = calculatorUnderTest.litresToGallons(3.78541); assertThat(actualLitres).isCloseTo(1.0, withinPercentage(0.01)); } @Test @DisplayName("L'aire d'un disque de rayon 1 doit valoir PI.") - public void radiusToAreaOfCircle_returnsPi_whenWeHaveARadiusOfOne() { + void radiusToAreaOfCircle_returnsPi_whenWeHaveARadiusOfOne() { Double actualArea = calculatorUnderTest.radiusToAreaOfCircle(1.0); assertThat(actualArea).isCloseTo(PI, withinPercentage(0.01)); } diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java index 31abf37..a86975f 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/DoubleCalculatorTest.java @@ -4,17 +4,17 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -public class DoubleCalculatorTest { + class DoubleCalculatorTest { private Calculator calculatorUnderTest; @BeforeEach - public void initCalculator() { + void initCalculator() { calculatorUnderTest = new Calculator(); } @Test - @Disabled("Test ambigu et hors limite du type double") - public void subTwoDoubleNumbers_shouldReturnsTheCorrectAnswer() { + @Disabled("Test ambigue et hors limite du type double") + void subTwoDoubleNumbers_shouldReturnsTheCorrectAnswer() { // GIVEN // WHEN diff --git a/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java b/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java index a798cd2..06df414 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/domain/StatisticsCalculatorTest.java @@ -16,7 +16,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class StatisticsCalculatorTest { + class StatisticsCalculatorTest { @Spy IntSummaryStatistics summaryStatistics = new IntSummaryStatistics(); @@ -24,12 +24,12 @@ public class StatisticsCalculatorTest { StatisticsCalculator underTest; @BeforeEach - public void setUp() { + void setUp() { underTest = new StatisticsCalculator(summaryStatistics); } @Test - public void average_shouldSample_allIntegersProvided() { + void average_shouldSample_allIntegersProvided() { final ArgumentCaptor sampleCaptor = ArgumentCaptor.forClass(Integer.class); final List samples = Arrays.asList(2, 8, 5, 3, 7); @@ -41,7 +41,7 @@ public void average_shouldSample_allIntegersProvided() { } @Test - public void average_shouldReturnTheMean_ofAListOfIntegers() { + void average_shouldReturnTheMean_ofAListOfIntegers() { final List samples = Arrays.asList(2, 8, 5, 3, 7); final Integer result = underTest.average(samples); diff --git a/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java new file mode 100644 index 0000000..73d7765 --- /dev/null +++ b/src/test/java/tech/zerofiltre/testing/calcul/e2e/MultiplicationJourneyE2ETest.java @@ -0,0 +1,72 @@ +package tech.zerofiltre.testing.calcul.e2e; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.github.bonigarcia.wdm.WebDriverManager; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +class MultiplicationJourneyE2ETest { + + @LocalServerPort + private int port; + + private WebDriver webDriver; + private String baseUrl; + + @BeforeAll + static void setUpFireFoxDriver() { + WebDriverManager.firefoxdriver().setup(); + } + + @BeforeEach + void setUpWebDriver() { + webDriver = new FirefoxDriver(); + baseUrl = "http://localhost:" + port + "/calculator"; + + } + + @AfterEach + void quitWebDriver() { + if (webDriver != null) { + webDriver.quit(); + } + } + + @Test + void multiplyTwoBySixteenMustReturn32() { + + //GIVEN + webDriver.get(baseUrl); + WebElement leftField = webDriver.findElement(By.id("left")); + WebElement typeDropDown = webDriver.findElement(By.id("type")); + WebElement rightField = webDriver.findElement(By.id("right")); + WebElement submitButton = webDriver.findElement(By.id("submit")); + + //WHEN + leftField.sendKeys("2"); + typeDropDown.sendKeys("x"); + rightField.sendKeys("16"); + submitButton.click(); + + //THEN + WebDriverWait waiter = new WebDriverWait(webDriver, 5); + WebElement solutionElement = waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("solution"))); + String solution = solutionElement.getText(); + assertThat(solution).isEqualTo("32"); + } + + +} diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java index 55f708f..89e9b91 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/BatchCalculatorServiceTest.java @@ -25,7 +25,7 @@ import tech.zerofiltre.testing.calcul.domain.model.CalculationType; @ExtendWith(MockitoExtension.class) -public class BatchCalculatorServiceTest { + class BatchCalculatorServiceTest { @Mock CalculatorService calculatorService; @@ -35,7 +35,7 @@ public class BatchCalculatorServiceTest { BatchCalculatorService batchCalculatorServiceNoMock; @BeforeEach - public void init() { + void init() { batchCalculatorService = new BatchCalculatorServiceImpl(calculatorService); batchCalculatorServiceNoMock = new BatchCalculatorServiceImpl( @@ -44,7 +44,7 @@ public void init() { } @Test - public void givenOperationsList_whenbatchCalculate_thenReturnsCorrectAnswerList() + void givenOperationsList_whenbatchCalculate_thenReturnsCorrectAnswerList() throws IOException, URISyntaxException { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); @@ -57,7 +57,7 @@ public void givenOperationsList_whenbatchCalculate_thenReturnsCorrectAnswerList( } @Test - public void givenOperationsList_whenbatchCalculate_thenCallsServiceWithCorrectArguments() { + void givenOperationsList_whenbatchCalculate_thenCallsServiceWithCorrectArguments() { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); final ArgumentCaptor calculationModelCaptor = ArgumentCaptor.forClass(CalculationModel.class); @@ -79,7 +79,7 @@ public void givenOperationsList_whenbatchCalculate_thenCallsServiceWithCorrectAr } @Test - public void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer() { + void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer() { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); when(calculatorService.calculate(any(CalculationModel.class))) @@ -113,7 +113,7 @@ public void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAns } @Test - public void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer2() { + void givenOperationsList_whenbatchCalculate_thenCallsServiceAndReturnsAnswer2() { // GIVEN final Stream operations = Arrays.asList("2 + 2", "5 - 4", "6 x 8", "9 / 3").stream(); when(calculatorService.calculate(any(CalculationModel.class))) diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java index 18f204b..dc6a2c3 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceIT.java @@ -3,29 +3,28 @@ import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; - import tech.zerofiltre.testing.calcul.domain.Calculator; import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; import tech.zerofiltre.testing.calcul.domain.model.CalculationType; -public class CalculatorServiceIT { +class CalculatorServiceIT { - // Mettre en place des objets réels non mockés - private final Calculator calculator = new Calculator(); - private final SolutionFormatter formatter = new SolutionFormatterImpl(); + // Mettre en place des objets réels non mockés + private final Calculator calculator = new Calculator(); + private final SolutionFormatter formatter = new SolutionFormatterImpl(); - // Initialiser la classe à tester - private final CalculatorService underTest = new CalculatorServiceImpl(calculator, formatter); + // Initialiser la classe à tester + private final CalculatorService underTest = new CalculatorServiceImpl(calculator, formatter); - @Test - public void calculatorService_shouldCalculateASolution_whenGivenACalculationModel() { - // GIVEN - final CalculationModel calculation = new CalculationModel(CalculationType.ADDITION, - 100, 101); - // WHEN - final CalculationModel result = underTest.calculate(calculation); + @Test + void calculatorService_shouldCalculateASolution_whenGivenACalculationModel() { + // GIVEN + final CalculationModel calculation = new CalculationModel(CalculationType.ADDITION, + 100, 101); + // WHEN + final CalculationModel result = underTest.calculate(calculation); - // THEN - assertThat(result.getSolution()).isEqualTo(201); - } + // THEN + assertThat(result.getSolution()).isEqualTo(201); + } } diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java index 8c18448..11334d6 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/CalculatorServiceTest.java @@ -9,133 +9,131 @@ import static org.mockito.Mockito.when; import java.util.Random; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - import tech.zerofiltre.testing.calcul.domain.Calculator; import tech.zerofiltre.testing.calcul.domain.model.CalculationModel; import tech.zerofiltre.testing.calcul.domain.model.CalculationType; @ExtendWith(MockitoExtension.class) -public class CalculatorServiceTest { - - @Mock - Calculator calculator; - - @Mock - SolutionFormatter solutionFormatter; - - CalculatorService classUnderTest; - - @BeforeEach - public void init() { - classUnderTest = new CalculatorServiceImpl(calculator, solutionFormatter); - } - - @Test - public void calculate_shouldUseCalculator_forAddition() { - // GIVEN - when(calculator.add(1, 2)).thenReturn(3); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.ADDITION, 1, 2)).getSolution(); - - // THEN - verify(calculator).add(1, 2); - assertThat(result).isEqualTo(3); - } - - @Test - public void calculate_shouldUseCalculator_forSubstraction() { - // GIVEN - when(calculator.sub(3, 2)).thenReturn(1); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.SUBTRACTION, 3, 2)) - .getSolution(); - - // THEN - verify(calculator).sub(3, 2); - assertThat(result).isEqualTo(1); - } - - @Test - public void calculate_shouldUseCalculator_forMultiplication() { - // GIVEN - when(calculator.multiply(-3, 2)).thenReturn(-6); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.MULTIPLICATION, -3, 2)) - .getSolution(); - - // THEN - verify(calculator).multiply(-3, 2); - assertThat(result).isEqualTo(-6); - } - - @Test - public void calculate_shouldUseCalculator_forDivision() { - // GIVEN - when(calculator.divide(6, 3)).thenReturn(2); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.DIVISION, 6, 3)) - .getSolution(); - - // THEN - verify(calculator).divide(6, 3); - assertThat(result).isEqualTo(2); - } - - @Test - public void calculate_shouldUseCalculator_forAnyAddition() { - // GIVEN - final Random r = new Random(); - when(calculator.add(any(Integer.class), any(Integer.class))).thenReturn(3); - - // WHEN - final int result = classUnderTest.calculate( - new CalculationModel(CalculationType.ADDITION, r.nextInt(), r.nextInt())).getSolution(); - - // THEN - verify(calculator, times(1)).add(any(Integer.class), any(Integer.class)); - verify(calculator, never()).sub(any(Integer.class), any(Integer.class)); - assertThat(result).isEqualTo(3); - } - - @Test - public void calculate_shouldThrowIllegalArgumentAxception_forADivisionBy0() { - // GIVEN - when(calculator.divide(1, 0)).thenThrow(new ArithmeticException()); - - // WHEN - assertThrows(IllegalArgumentException.class, () -> classUnderTest.calculate( - new CalculationModel(CalculationType.DIVISION, 1, 0))); - - // THEN - verify(calculator, times(1)).divide(1, 0); - } - - @Test - public void calculate_shouldFormatSolution_forAnAddition() { - // GIVEN - when(calculator.add(10000, 3000)).thenReturn(13000); - when(solutionFormatter.format(13000)).thenReturn("13 000"); - - // WHEN - final String formattedResult = classUnderTest.calculate( - new CalculationModel(CalculationType.ADDITION, 10000, 3000)).getFormattedSolution(); - - // THEN - assertThat(formattedResult).isEqualTo("13 000"); - } +class CalculatorServiceTest { + + @Mock + Calculator calculator; + + @Mock + SolutionFormatter solutionFormatter; + + CalculatorService classUnderTest; + + @BeforeEach + void init() { + classUnderTest = new CalculatorServiceImpl(calculator, solutionFormatter); + } + + @Test + void calculate_shouldUseCalculator_forAddition() { + // GIVEN + when(calculator.add(1, 2)).thenReturn(3); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.ADDITION, 1, 2)).getSolution(); + + // THEN + verify(calculator).add(1, 2); + assertThat(result).isEqualTo(3); + } + + @Test + void calculate_shouldUseCalculator_forSubstraction() { + // GIVEN + when(calculator.sub(3, 2)).thenReturn(1); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.SUBTRACTION, 3, 2)) + .getSolution(); + + // THEN + verify(calculator).sub(3, 2); + assertThat(result).isEqualTo(1); + } + + @Test + void calculate_shouldUseCalculator_forMultiplication() { + // GIVEN + when(calculator.multiply(-3, 2)).thenReturn(-6); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.MULTIPLICATION, -3, 2)) + .getSolution(); + + // THEN + verify(calculator).multiply(-3, 2); + assertThat(result).isEqualTo(-6); + } + + @Test + void calculate_shouldUseCalculator_forDivision() { + // GIVEN + when(calculator.divide(6, 3)).thenReturn(2); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.DIVISION, 6, 3)) + .getSolution(); + + // THEN + verify(calculator).divide(6, 3); + assertThat(result).isEqualTo(2); + } + + @Test + void calculate_shouldUseCalculator_forAnyAddition() { + // GIVEN + final Random r = new Random(); + when(calculator.add(any(Integer.class), any(Integer.class))).thenReturn(3); + + // WHEN + final int result = classUnderTest.calculate( + new CalculationModel(CalculationType.ADDITION, r.nextInt(), r.nextInt())).getSolution(); + + // THEN + verify(calculator, times(1)).add(any(Integer.class), any(Integer.class)); + verify(calculator, never()).sub(any(Integer.class), any(Integer.class)); + assertThat(result).isEqualTo(3); + } + + @Test + void calculate_shouldThrowIllegalArgumentAxception_forADivisionBy0() { + // GIVEN + when(calculator.divide(1, 0)).thenThrow(new ArithmeticException()); + + // WHEN + CalculationModel calculationModel = new CalculationModel(CalculationType.DIVISION, 1, 0); + assertThrows(IllegalArgumentException.class, () -> classUnderTest.calculate(calculationModel)); + + // THEN + verify(calculator, times(1)).divide(1, 0); + } + + @Test + void calculate_shouldFormatSolution_forAnAddition() { + // GIVEN + when(calculator.add(10000, 3000)).thenReturn(13000); + when(solutionFormatter.format(13000)).thenReturn("13 000"); + + // WHEN + final String formattedResult = classUnderTest.calculate( + new CalculationModel(CalculationType.ADDITION, 10000, 3000)).getFormattedSolution(); + + // THEN + assertThat(formattedResult).isEqualTo("13 000"); + } } diff --git a/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java b/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java index 15f0006..3e3ab4a 100644 --- a/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java +++ b/src/test/java/tech/zerofiltre/testing/calcul/service/SolutionFormatterTest.java @@ -5,25 +5,25 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class SolutionFormatterTest { +class SolutionFormatterTest { - private SolutionFormatter solutionFormatter; + private SolutionFormatter solutionFormatter; - @BeforeEach - public void initFormatter() { - solutionFormatter = new SolutionFormatterImpl(); - } + @BeforeEach + void initFormatter() { + solutionFormatter = new SolutionFormatterImpl(); + } - @Test - public void format_shouldFormatAnyBigNumber() { - // GIVEN - final int number = 1234567890; + @Test + void format_shouldFormatAnyBigNumber() { + // GIVEN + final int number = 1234567890; - // WHEN - final String result = solutionFormatter.format(number); + // WHEN + final String result = solutionFormatter.format(number); - // THEN - assertThat(result).isEqualTo("1 234 567 890"); - } + // THEN + assertThat(result).isEqualTo("1 234 567 890"); + } }