tdd-demo-forumphp2020 icon indicating copy to clipboard operation
tdd-demo-forumphp2020 copied to clipboard

Live coding examples used during Forum PHP 2020 talk "Too many mocks killed the test: What Hexagonal Architecture has changed"

TDD Demo - ForumPHP 2020

Build Status

Live coding examples used during Forum PHP 2020 talk:

For a bit of theory, see :fr: De CRUD à DDD, comment Meetic a sauvé son legacy

Steps by step refactoring

:warning: Warning : Only steps 1 & 2 are really considered bad. Next steps just show different testing styles.

  1. bad_implementation branch contains :
    • Architecture mistakes according to Hexagonal architecture (aka Port & Adapters)
    • Tests too much coupled with implementation details, and an incorrect usage of mocks
  2. bad_tests branch (see Pull Request) only fixes (some) hexagonal mistakes. Many obscure changes are required in the tests, proving they do not help much during refactoring
  3. integration_infra_medium_domain branch (see Pull Request) split tests this way:
    • Domain logic (Application/Domain folders): medium Unit tests, mocking only infrastructure
    • Technical logic (Infrastructure folder): integration tests for each specific technology
  4. integration_infra_medium_domain_wiremock branch (see Pull Request) only replaces Guzzle MockHandler with Wiremock, decoupling HTTP tests with the library being used for HTTP calls.
  5. integration_infra_medium_domain_no_di branch (see Pull Request) removes Dependency Injection Container usage and manually build tested classes instead.
  6. integration_infra_sociable branch (see Pull Request) replaces medium sized tests with Overlapping Sociable Tests to allow easily test and evolve individual behaviours (ex : class serialization) while still being able to split/merge/refactor classes inside some class clusters by not checking specific calls between them.
  7. mock_secondary_ports_in_behat branch (see Pull Request): Mock Secondary Ports (according to Hexagonal architecture) in Behat. Makes behat tests much faster and easier to write. Pre-requisite : well defined secondary ports and Integration tests on their Infrastructure layer implementation.

API documentation

  • Local : docs/openapi.yml
  • Github Pages : https://jmlamodiere.github.io/tdd-demo-forumphp2020
  • Swaggger Hub (with SwaggerHub API Auto Mocking activated) : https://app.swaggerhub.com/apis/JMLamodiere/tdd-demo_forum_php_2020/1.0.0

Example :

curl -i -X PUT "https://virtserver.swaggerhub.com/JMLamodiere/tdd-demo_forum_php_2020/1.0.0/runningsessions/42" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"id\":42,\"distance\":5.5,\"shoes\":\"Adadis Turbo2\"}"

Makefile

Run make or make help to see available commands.

Test environment

Pre-requisites :

Run tests with:

make install
make test

Dev environment

Pre-requisites (see composer.json) :

Create an App on AccuWeather and copy your API Key:

# in /.env.dev.local
ACCUWEATHER_API_KEY=xxx

Start local dev environment with:

composer install
make start
  • Symfony homepage (404): https://127.0.0.1:8000/
  • Symfony profiler: https://127.0.0.1:8000/_profiler/

Postgresql

To access Postgresql database, configure a tool such as Database Tools and SQL included in PHPStorm:

  • URL: jdbc:postgresql://localhost:32774/forumphp (replace 32774 with the port given by make ps command)
  • login: forumphp
  • password: forumphp (see docker-compose.yml)

Wiremock

  • Local server: https://hub.docker.com/r/rodolpheche/wiremock/ (see docker-compose.yml)
  • PHP Client: https://github.com/rowanhill/wiremock-php (used in PHP tests)

See Swagger UI documentation at http://localhost:32775/__admin/swagger-ui/

Replace 32775 with the port given by make ps command