|
1 | 1 | # Testing using hexagonal architecture |
2 | 2 |
|
3 | | -Use a bank example to demonstrate how using a hexagonal architecture can help to test an application. |
| 3 | +Use a bank example to demonstrate how using a hexagonal architecture can help to test an application functionality at |
| 4 | +different scales. |
4 | 5 |
|
5 | 6 | ## Structure |
6 | 7 |
|
7 | 8 | The application is split into 3 modules: |
8 | 9 |
|
9 | 10 | - domain: business logic driving how the bank behaves. |
10 | | -- http: api to expose the bank functionality via http. |
11 | | -- web: dummy web ui driving the application. |
| 11 | +- HTTP: API to expose the bank functionality via HTTP. |
| 12 | +- web: dummy web UI driving the application. |
12 | 13 |
|
13 | 14 | ## Solution |
14 | 15 |
|
15 | 16 | The business logic of the bank is fully implemented as part of the domain. As per typical hexagonal architecture, where |
16 | 17 | an interaction is needed with the outside world, a contract (port) is defined to state how the application expects that |
17 | | -to happen. In this example only 2 are defined: |
| 18 | +to happen. In this example, only 2 are defined: |
18 | 19 |
|
19 | | -- one that allows to drive the application by exposing all the banks capabilities - driving or primary port; |
| 20 | +- one that allows driving the application by exposing all the bank's capabilities - driving or primary port; |
20 | 21 | - and another to define how the bank accounts data is stored and queried - driven or secondary port. |
21 | 22 |
|
22 | | -The isolation of the business logic that the hexagonal architecture provides, allows components to have a single |
23 | | -purpose, only mapping from the technology in use to business terms. This is considered one of its main benefits but here |
24 | | -we attempt to show how it can also greatly help testing. |
| 23 | +The isolation of the business logic that the hexagonal architecture enforces, limits components to mapping the |
| 24 | +technology in use to business terms. This is considered one of its main benefits, but here we attempt to show how it can |
| 25 | +also greatly help testing. |
25 | 26 |
|
26 | 27 | Having every component in the system defined in terms of contracts means that writing tests based on those very same |
27 | | -contracts allows to have a single suite of tests that can be run against any layer of the system, providing excellent |
28 | | -test coverage for the whole system with small effort. |
| 28 | +contracts allow having a single suite of tests that can be run against any layer of the system, providing excellent test |
| 29 | +coverage for the whole system with small effort. |
29 | 30 |
|
30 | | -This example mainly focuses in the contract defining how the business behaves as it highlights the benefits of the |
31 | | -approach, but the same strategy can be applied to any other port. For examples, if there were multiple ways to |
32 | | -store/query accounts, a single test could be defined to test all of them. |
| 31 | +This example mainly focuses on the contract defining how the business behaves as it highlights the benefits of the |
| 32 | +approach. Still, the same strategy can be applied to any other port. For example, if there were multiple ways to |
| 33 | +store/query accounts, a single test could be defined to test the contract for all of them. |
33 | 34 |
|
34 | 35 | ## How to run |
35 | 36 |
|
36 | | -The full stack can be run in a single jvm for demonstration purposes using `Main.kt` in the `web` project: |
| 37 | +The full stack can be run in a single JVM for demonstration purposes using `Main.kt` in the `web` project: |
37 | 38 | ```shell |
38 | 39 | ./gradlew :web:run |
39 | 40 | ``` |
40 | 41 |
|
41 | 42 | ## Technology |
42 | 43 |
|
43 | | -The intention is to have as simple as possible code so very few external dependencies are used. It's implemented in |
| 44 | +The intention is to have as simple as possible code, so very few external dependencies are used. It's implemented in |
44 | 45 | [kotlin](https://kotlinlang.org), my preferred programming language, and the only production dependency is the |
45 | | -[http4k](http://http4k.org/) library, which is used to define the http api as well as the server templating in the ui. |
| 46 | +[http4k](http://http4k.org/) library, which is used to define the HTTP API and the server templating in the UI. |
46 | 47 |
|
47 | 48 | For testing, only [junit5](https://junit.org/junit5/) and [hamkrest](https://github.com/npryce/hamkrest) are used. |
0 commit comments