![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0431.png)
the Internet, or the UI—and trying to keep them separate from the core business logic
of your application.
Ports and Adapters/Hexagonal/Clean Architecture
Integrated tests are most useful at the
boundaries
of a system—at the points where our
code integrates with external systems, like a database, filesystem, or UI components.
Similarly, it’s at the boundaries that the downsides of test isolation and mocks are at
their worst, because it’s at the boundaries that you’re most likely to be annoyed if your
tests are tightly coupled to an implementation, or to need more reassurance that things
are integrated properly.
Conversely, code at the
core
of our application—code that’s purely concerned with our
business domain and business rules, code that’s entirely under our control—this code
has less need for integrated tests, since we control and understand all of it.
So one way of getting what we want is to try and minimise the amount of our code that
has to deal with boundaries. Then we test our core business logic with isolated tests and
test our integration points with integrated tests.
Steve Freeman and Nat Pryce, in their book
Growing Object-Oriented Software, call
this approach “Ports and Adapters” (see
Figure 22-1 ).
We actually started moving towards a ports and adapters architecture in
Chapter 19 ,when we found that writing isolated unit tests was encouraging us to push ORM code
out of the main application, and hide it in helper functions from the model layer.
This pattern is also sometimes known as “The Clean architecture” or “Hexagonal Ar‐
chitecture”. See the further reading section at the end for more info.
Functional Core, Imperative Shell
Gary Bernhardt pushes this further, recommending an architecture he calls “Functional
Core, Imperative Shell”, whereby the “shell” of the application, the place where interac‐
tion with boundaries happens, follows the imperative programming paradigm, and can
be tested by integrated tests, acceptance tests, or even (gasp!) not at all, if it’s keptminimal
enough. But the core of the application is actually written following the functional pro‐
gramming paradigm (complete with the “no side effects” corollary), which actually
allows fully isolated, “pure” unit tests,
entirely without mocks
.
Check out Gary’s presentation titled
“Boundaries”for more on this approach.
Architectural Solutions
|
403