#1313 Add Separated Interface design pattern
This commit is contained in:
		
							
								
								
									
										119
									
								
								separated-interface/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								separated-interface/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| --- | ||||
| layout: pattern | ||||
| title: Separated Interface | ||||
| folder: separated-interface | ||||
| permalink: /patterns/separated-interface/ | ||||
| categories: Architectural | ||||
| tags: | ||||
|  - Decoupling | ||||
| --- | ||||
|  | ||||
|  | ||||
| ## Intent | ||||
| Separate the interface definition and implementation in different packages. This allows the client to be completly unaware of the implementation. | ||||
|  | ||||
| ## Explanation | ||||
|  | ||||
| Real world example | ||||
|  | ||||
| > An Invoice generator may be created with ability to use different Tax calculators that may be added in the invoice depending upon type of purchase, region etc.          | ||||
|  | ||||
| In plain words | ||||
|  | ||||
| > Separated interface pattern encourages to keep the implementations of an interface decoupled from the client and its definition, so the client is not dependent on the implementation. | ||||
|  | ||||
| A client code may abstract some specific functionality to an interface, and define the definition of the interface as an SPI. Another package may implement this interface definition with a concrete logic, which will be injected into the client code at runtime (with a third class, injecting the implementation in the client) or at compile time (using Plugin pattern with some configurable file). | ||||
|  | ||||
| **Programmatic Example** | ||||
|  | ||||
| **Client** An Invoice generator class accepts the cost of the product and calculates the total amount payable inclusive of tax | ||||
|  | ||||
| ```java | ||||
| public class InvoiceGenerator { | ||||
|  | ||||
|   private final TaxCalculator taxCalculator; | ||||
|  | ||||
|   private final double amount; | ||||
|  | ||||
|   public InvoiceGenerator(double amount, TaxCalculator taxCalculator) { | ||||
|     this.amount = amount; | ||||
|     this.taxCalculator = taxCalculator; | ||||
|   } | ||||
|  | ||||
|   public double getAmountWithTax() { | ||||
|     return amount + taxCalculator.calculate(amount); | ||||
|   } | ||||
|  | ||||
| } | ||||
| ``` | ||||
| The tax calculation logic is delegated to the ```TaxCalculator``` interface | ||||
|  | ||||
| ```java | ||||
|  | ||||
| public interface TaxCalculator { | ||||
|  | ||||
|   double calculate(double amount); | ||||
|  | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| **Implementation package** | ||||
| In another package (which the client is completely unaware of) there exist multiple implementations of the ```TaxCalculator``` interface | ||||
| ```ForeignTax``` which levies 60% tax for international products. | ||||
| ```java | ||||
| public class ForeignTax implements TaxCalculator { | ||||
|  | ||||
|   public static final double TAX_PERCENTAGE = 60; | ||||
|  | ||||
|   @Override | ||||
|   public double calculate(double amount) { | ||||
|     return amount * TAX_PERCENTAGE / 100.0; | ||||
|   } | ||||
|  | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ```DomesticTax``` which levies 20% tax for international products. | ||||
| ```java | ||||
| public class DomesticTax implements TaxCalculator { | ||||
|  | ||||
|   public static final double TAX_PERCENTAGE = 20; | ||||
|  | ||||
|   @Override | ||||
|   public double calculate(double amount) { | ||||
|     return amount * TAX_PERCENTAGE / 100.0; | ||||
|   } | ||||
|  | ||||
| } | ||||
| ``` | ||||
|  | ||||
| These both implementations are instantiated and injected in the client class by the ```App.java``` class | ||||
|  | ||||
| ```java | ||||
|     var internationalProductInvoice = new InvoiceGenerator(PRODUCT_COST, new ForeignTax()); | ||||
|  | ||||
|     LOGGER.info("Foreign Tax applied: {}", "" + internationalProductInvoice.getAmountWithTax()); | ||||
|  | ||||
|     var domesticProductInvoice = new InvoiceGenerator(PRODUCT_COST, new DomesticTax()); | ||||
|  | ||||
|     LOGGER.info("Domestic Tax applied: {}", "" + domesticProductInvoice.getAmountWithTax()); | ||||
| ``` | ||||
|  | ||||
| ## Class diagram | ||||
|  | ||||
|  | ||||
| ## Applicability | ||||
| Use the Separated interface pattern when | ||||
|  | ||||
| * You are developing a framework package, and your framework needs to call some application code through interfaces. | ||||
| * You have separate packages implementing the functionalities which may be plugged in your client code at runtime or compile-time. | ||||
| * Your code resides in a layer that is not allowed to call the interface implementation layer by rule. For example, a domain layer needs to call a data mapper. | ||||
|  | ||||
| ## Tutorial  | ||||
|  | ||||
| * [Separated Interface Tutorial](https://www.youtube.com/watch?v=d3k-hOA7k2Y) | ||||
|  | ||||
| ## Credits | ||||
|  | ||||
| * [Martin Fowler](https://www.martinfowler.com/eaaCatalog/separatedInterface.html) | ||||
							
								
								
									
										
											BIN
										
									
								
								separated-interface/etc/class_diagram.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								separated-interface/etc/class_diagram.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 32 KiB | 
							
								
								
									
										36
									
								
								separated-interface/etc/separated-interface.urm.puml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								separated-interface/etc/separated-interface.urm.puml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| @startuml | ||||
| package com.iluwatar.separatedinterface { | ||||
|   class App { | ||||
|     - LOGGER : Logger {static} | ||||
|     + PRODUCT_COST : double {static} | ||||
|     + App() | ||||
|     + main(args : String[]) {static} | ||||
|   } | ||||
| } | ||||
| package com.iluwatar.separatedinterface.taxes { | ||||
|   class DomesticTax { | ||||
|     + TAX_PERCENTAGE : double {static} | ||||
|     + DomesticTax() | ||||
|     + calculate(amount : double) : double | ||||
|   } | ||||
|   class ForeignTax { | ||||
|     + TAX_PERCENTAGE : double {static} | ||||
|     + ForeignTax() | ||||
|     + calculate(amount : double) : double | ||||
|   } | ||||
| } | ||||
| package com.iluwatar.separatedinterface.invoice { | ||||
|   class InvoiceGenerator { | ||||
|     - amount : double | ||||
|     - taxCalculator : TaxCalculator | ||||
|     + InvoiceGenerator(amount : double, taxCalculator : TaxCalculator) | ||||
|     + getAmountWithTax() : double | ||||
|   } | ||||
|   interface TaxCalculator { | ||||
|     + calculate(double) : double {abstract} | ||||
|   } | ||||
| } | ||||
| InvoiceGenerator -->  "-taxCalculator" TaxCalculator | ||||
| DomesticTax ..|> TaxCalculator  | ||||
| ForeignTax ..|> TaxCalculator  | ||||
| @enduml | ||||
							
								
								
									
										71
									
								
								separated-interface/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								separated-interface/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| <?xml version="1.0"?> | ||||
| <!-- | ||||
|  | ||||
|     The MIT License | ||||
|     Copyright © 2014-2019 Ilkka Seppälä | ||||
|  | ||||
|     Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|     of this software and associated documentation files (the "Software"), to deal | ||||
|     in the Software without restriction, including without limitation the rights | ||||
|     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|     copies of the Software, and to permit persons to whom the Software is | ||||
|     furnished to do so, subject to the following conditions: | ||||
|  | ||||
|     The above copyright notice and this permission notice shall be included in | ||||
|     all copies or substantial portions of the Software. | ||||
|  | ||||
|     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|     THE SOFTWARE. | ||||
|  | ||||
| --> | ||||
| <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||||
|   <modelVersion>4.0.0</modelVersion> | ||||
|   <parent> | ||||
|     <groupId>com.iluwatar</groupId> | ||||
|     <artifactId>java-design-patterns</artifactId> | ||||
|     <version>1.24.0-SNAPSHOT</version> | ||||
|   </parent> | ||||
|   <artifactId>separated-interface</artifactId> | ||||
|   <dependencies> | ||||
|     <dependency> | ||||
|       <groupId>org.junit.jupiter</groupId> | ||||
|       <artifactId>junit-jupiter-engine</artifactId> | ||||
|       <scope>test</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.junit.jupiter</groupId> | ||||
|       <artifactId>junit-jupiter-params</artifactId> | ||||
|       <scope>test</scope> | ||||
|     </dependency> | ||||
|     <dependency> | ||||
|       <groupId>org.mockito</groupId> | ||||
|       <artifactId>mockito-core</artifactId> | ||||
|       <scope>test</scope> | ||||
|     </dependency> | ||||
|   </dependencies> | ||||
|   <build> | ||||
|     <plugins> | ||||
|       <plugin> | ||||
|         <groupId>org.apache.maven.plugins</groupId> | ||||
|         <artifactId>maven-assembly-plugin</artifactId> | ||||
|         <executions> | ||||
|           <execution> | ||||
|             <configuration> | ||||
|               <archive> | ||||
|                 <manifest> | ||||
|                   <mainClass>com.iluwatar.separatedinterface.App</mainClass> | ||||
|                 </manifest> | ||||
|               </archive> | ||||
|             </configuration> | ||||
|           </execution> | ||||
|         </executions> | ||||
|       </plugin> | ||||
|     </plugins> | ||||
|   </build> | ||||
| </project> | ||||
| @@ -0,0 +1,61 @@ | ||||
| /* | ||||
|  * The MIT License | ||||
|  * Copyright © 2014-2019 Ilkka Seppälä | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package com.iluwatar.separatedinterface; | ||||
|  | ||||
| import com.iluwatar.separatedinterface.invoice.InvoiceGenerator; | ||||
| import com.iluwatar.separatedinterface.taxes.DomesticTax; | ||||
| import com.iluwatar.separatedinterface.taxes.ForeignTax; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| /** | ||||
|  * <p>The Strategy pattern (also known as the policy pattern) is a software design pattern that | ||||
|  * enables an algorithm's behavior to be selected at runtime.</p> | ||||
|  * | ||||
|  * <p>Before Java 8 the Strategies needed to be separate classes forcing the developer | ||||
|  * to write lots of boilerplate code. With modern Java it is easy to pass behavior with method | ||||
|  * references and lambdas making the code shorter and more readable.</p> | ||||
|  * | ||||
|  */ | ||||
| public class App { | ||||
|  | ||||
|   private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||||
|  | ||||
|   public static final double PRODUCT_COST = 50.0; | ||||
|  | ||||
|   /** | ||||
|    * Program entry point. | ||||
|    * | ||||
|    * @param args command line args | ||||
|    */ | ||||
|   public static void main(String[] args) { | ||||
|     //Create the invoice generator with product cost as 50 and foreign product tax | ||||
|     var internationalProductInvoice = new InvoiceGenerator(PRODUCT_COST, new ForeignTax()); | ||||
|     LOGGER.info("Foreign Tax applied: {}", "" + internationalProductInvoice.getAmountWithTax()); | ||||
|  | ||||
|     //Create the invoice generator with product cost as 50 and domestic product tax | ||||
|     var domesticProductInvoice = new InvoiceGenerator(PRODUCT_COST, new DomesticTax()); | ||||
|     LOGGER.info("Domestic Tax applied: {}", "" + domesticProductInvoice.getAmountWithTax()); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| package com.iluwatar.separatedinterface.invoice; | ||||
|  | ||||
| /** | ||||
|  * InvoiceGenerator class generates an invoice, accepting the product cost and calculating the total | ||||
|  * price payable inclusive tax (calculated by {@link TaxCalculator}) | ||||
|  */ | ||||
| public class InvoiceGenerator { | ||||
|  | ||||
|   /** | ||||
|    * The TaxCalculator interface to calculate the payable tax. | ||||
|    */ | ||||
|   private final TaxCalculator taxCalculator; | ||||
|  | ||||
|   /** | ||||
|    * The base product amount without tax. | ||||
|    */ | ||||
|   private final double amount; | ||||
|  | ||||
|   public InvoiceGenerator(double amount, TaxCalculator taxCalculator) { | ||||
|     this.amount = amount; | ||||
|     this.taxCalculator = taxCalculator; | ||||
|   } | ||||
|  | ||||
|   public double getAmountWithTax() { | ||||
|     return amount + taxCalculator.calculate(amount); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| /* | ||||
|  * The MIT License | ||||
|  * Copyright © 2014-2019 Ilkka Seppälä | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package com.iluwatar.separatedinterface.invoice; | ||||
|  | ||||
| public interface TaxCalculator { | ||||
|  | ||||
|   double calculate(double amount); | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * The MIT License | ||||
|  * Copyright © 2014-2019 Ilkka Seppälä | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package com.iluwatar.separatedinterface.taxes; | ||||
|  | ||||
| import com.iluwatar.separatedinterface.invoice.TaxCalculator; | ||||
|  | ||||
| /** | ||||
|  * TaxCalculator for Domestic goods with 20% tax. | ||||
|  */ | ||||
| public class DomesticTax implements TaxCalculator { | ||||
|  | ||||
|   public static final double TAX_PERCENTAGE = 20; | ||||
|  | ||||
|   @Override | ||||
|   public double calculate(double amount) { | ||||
|     return amount * TAX_PERCENTAGE / 100.0; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * The MIT License | ||||
|  * Copyright © 2014-2019 Ilkka Seppälä | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package com.iluwatar.separatedinterface.taxes; | ||||
|  | ||||
| import com.iluwatar.separatedinterface.invoice.TaxCalculator; | ||||
|  | ||||
| /** | ||||
|  * TaxCalculator for foreign goods with 60% tax. | ||||
|  */ | ||||
| public class ForeignTax implements TaxCalculator { | ||||
|  | ||||
|   public static final double TAX_PERCENTAGE = 60; | ||||
|  | ||||
|   @Override | ||||
|   public double calculate(double amount) { | ||||
|     return amount * TAX_PERCENTAGE / 100.0; | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,41 @@ | ||||
| /* | ||||
|  * The MIT License | ||||
|  * Copyright © 2014-2019 Ilkka Seppälä | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| package com.iluwatar.separatedinterface; | ||||
|  | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| import com.iluwatar.separatedinterface.App; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; | ||||
|  | ||||
| /** | ||||
|  * Application test. | ||||
|  */ | ||||
| class AppTest { | ||||
|  | ||||
|   @Test | ||||
|   void shouldExecuteWithoutException() { | ||||
|     assertDoesNotThrow(() -> App.main(new String[]{})); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| package com.iluwatar.separatedinterface.invoice; | ||||
|  | ||||
| import org.junit.jupiter.api.Assertions; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| import static org.mockito.Mockito.*; | ||||
|  | ||||
| public class InvoiceGeneratorTest { | ||||
|  | ||||
|   private InvoiceGenerator target; | ||||
|  | ||||
|   @Test | ||||
|   public void testGenerateTax() { | ||||
|     var productCost = 50.0; | ||||
|     var tax = 10.0; | ||||
|     TaxCalculator taxCalculatorMock = mock(TaxCalculator.class); | ||||
|     doReturn(tax).when(taxCalculatorMock).calculate(productCost); | ||||
|  | ||||
|     target = new InvoiceGenerator(productCost, taxCalculatorMock); | ||||
|  | ||||
|     Assertions.assertEquals(target.getAmountWithTax(), productCost + tax); | ||||
|     verify(taxCalculatorMock, times(1)).calculate(productCost); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,18 @@ | ||||
| package com.iluwatar.separatedinterface.taxes; | ||||
|  | ||||
| import org.junit.jupiter.api.Assertions; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class DomesticTaxTest { | ||||
|  | ||||
|   private DomesticTax target; | ||||
|  | ||||
|   @Test | ||||
|   public void testTaxCaluclation(){ | ||||
|     target = new DomesticTax(); | ||||
|  | ||||
|     var tax=target.calculate(100.0); | ||||
|     Assertions.assertEquals(tax,20.0); | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,18 @@ | ||||
| package com.iluwatar.separatedinterface.taxes; | ||||
|  | ||||
| import org.junit.jupiter.api.Assertions; | ||||
| import org.junit.jupiter.api.Test; | ||||
|  | ||||
| public class ForeignTaxTest { | ||||
|  | ||||
|   private ForeignTax target; | ||||
|  | ||||
|   @Test | ||||
|   public void testTaxCaluclation(){ | ||||
|     target = new ForeignTax(); | ||||
|  | ||||
|     var tax=target.calculate(100.0); | ||||
|     Assertions.assertEquals(tax,60.0); | ||||
|   } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user