Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Adapter Contract Testing - We don't want no moc...

Adapter Contract Testing - We don't want no mock trouble!

martinsson

April 18, 2025
Tweet

More Decks by martinsson

Other Decks in Technology

Transcript

  1. We don’t need no mock trouble Why do we shift

    away from using mock Photo de Jonathan Borba sur Unsplash
  2. But the tests are passing • A missed use case

    • Many layers of tests, with a bad mock somewhere • Surprise behavious of a dependency Bugs in prod Photo de Xavi Cabrera sur Unsplash
  3. Tech language - Not business facing Confusing intent Verbose Mock

    problems Test SUT Stub Spy Setup Veri fi cation Test SUT Simulator Other classes Setup Veri fi cation
  4. Domain The hexagonal opportunity Plugin behavior Domain Adapters Adapters Adapters

    Infrastructure Ports Infrastructure code Other adapter ✅
  5. Domain Simulators 🤖 Simulators 🤖 Infrastructure Ports Test The hexagonal

    opportunity Use simulators to test your domain with con fi dence Adapters Adapters
  6. Adapter contract test Test the real adapter de fi ne

    the contract Adapters Infrastructure Test Including anti-corruption layer ✍
  7. Use the contract to create strong simulators Adapters Infrastructure Test

    Including anti-corruption layer Simulator Contract = running the same test Adapter contract test ✍ 💪
  8. • Establish a contract with simulator against a DB •

    Establish a contract with a read- only dependency • Use simulators to test the domain with con fi dence Road-book high level view Photo de Jesse Bowser sur Unsplash
  9. Make groups of 2 ou 3 💡 Tips for pair/mob

    • Driver role : 
 Have the keyboard
 Responsible to translate ideas to code • Navigators role :
 Tells the driver what you want to be done • Switch roles often • If you have an idea : be a kind navigator Hands-on setup Photo de Halogen Condense sur Unsplash
  10. Hands-on setup Setup steps 1. Open the project fi le

    of your chosen language 2. Follow README instruction : 1. Start mongo db locally
 docker run --rm -p 27017:27017 --name mongo_contract_testing -d mongo 2. Start race server locally
 docker run --rm -d -p8000:8000 --name snail-race-server mathieucans/snail-race-server:latest 3. Execute requirement test If you are done : help others! 🤝
  11. Establish a contract with simulator against a DB • Write

    a test against a database • Extract the contract test • Use contract test to write a simulator Road-book Step 1 Photo de Glenn Carstens-Peters sur Unsplash
  12. Exercice 1 - Contract test a database Test the real

    adapter de fi ne the contract BetRepositoryMongoDb BetRepository MongoDbTest Mongo DB BetRepository
  13. Contract test a database 💡 Tips : • Don’t panic

    with mongo syntax. • Refers to MongoDbCheatSheet.md if needed Exercice 1
  14. Use Contract test to implement simulator BetRepositoryMongoDb BetRepository MongoDb Test

    Mongo DB BetRepository BetRepositorySimulator BetRepository Simulator Test BetRepository Contract
  15. Use Contract test to implement simulator JAVA WAY BetRepositoryMongoDb BetRepository

    MongoDb Test Mongo DB BetRepository BetRepositorySimulator BetRepository Simulator Test BetRepository Contract Inherit Inherit Setup only Setup only All tests are here ➡
  16. Demo - Establish contract with read-only dep. Contract test a

    read only provider RaceResultProviderHttp RaceResultProvider Http Test RaceResultProvider SnailRaceServer
  17. Read-only api 1. Make a contract with the dependency 1.

    Explore the endpoint with a unit test 2. Use the json response to create infrastructure types 3. Write a contract test that uses the desired port 4. Unit test the mapping (infra -> domain) with pure unit tests 2. Write simulator Roadbook Step 2
  18. Orange Restricted Anti corruption layer Domain side RaceResultProvider (Port) snail-

    race-server Infrastructure side SnailRaces SnailRace Podium Snail * 1 3
  19. Use Contract test to implement simulator RaceResultProviderHttp RaceResultProvider HttpTest RaceResultProvider

    RaceResultSimulatorSimulator RaceResultProvider SimulatorTest RaceResultProvider Contract Simulation SnailRaceServer
  20. Anti-Corruption Layer On steroids 1. Perform utterly daring validations and

    restructurings on the data from providers 👉 Allowing to build highly typed domain objects 2. Use the tests to run them on massive amounts of data 3. You’ve simpli fi ed the job for the domain and you can be certain the simpli fi cation is valid Tranformation Validation Normalisation Dirty DTO Clean Domain Object
  21. • ✅ External api changes • ✅ Refactorability of the

    adapter • ✅ No more technical tests Solved problems Photo de Bozhin Karaivanov sur Unsplash
  22. Real world: - 5G - 4G - 4G - 4G

    - 4g 💥 Solved problems False assumptions SOLVED Assumption: - 4G - 5G
  23. Exercice - Test application with confidence Use simulator to test

    your domain with con fi dence Domain RaceResultProviderSimulator BetRepositorySimulator Ports BetApplication Test
  24. Use simulators to test the domain with con fi dence

    • Use the simulators • Write a f….g test 😂 • Take time to appreciate: • domain language in tests • test brievety • fast feedback • con fi ence because we’re utterly close to the production behaviour 
 and interaction Roadbook Step3
  25. Domain rules The application can register bets • registering a

    bet is done by providing • gambler name • the 3 numbers of snails on the podium The application lists the winners according to last race ran. To win a bet : • The podium match exactly the race result • The bet has been registered at least 3 seconds before the race timestamp • A bet is valid only for the next race
  26. Exercice Use simulator to test your domain • ➡ Checkout

    branch start-step3 • Start writing tests
  27. • ✅ External api changes • ✅ Refactorability of the

    adapter • ✅ No more technical tests • ✅ Complexity isolation • ✅ False assumptions … Solved problems Photo de Bozhin Karaivanov sur Unsplash
  28. Contract tests in the CI • Put in a separate

    pipeline (possibly di ff erent triggers/periodicity) • Put in an optional pipeline/step • Use as uptime-bot • No CI ! - the main use is on dev machine
  29. Con fi ance dans les tests du domaine Tests de

    l’infra pertinents Migration de dépendance facile Refactorabilité ++ Isolation de la complexité Abstraction forte The 5 bene fi ts
  30. References • Contract Test - Martin Fowler • Testing Without

    Mocks - James Shore • Architecture Hexagonale : gestion de la complexité logicielle et de la dette technique - Julien Topçu • Outside-In Diamond TDD - Thomas Pierrain
  31. Orange Restricted Use contract test for production metrics • Use

    exactly same test to generate metrics on production • Useful when traffic still small • Better diagnostic • OPS can monitor them
  32. Example: gmail reply detection Gmail has no native way to

    check if an email has been replied to It can be implemented through threads Need to expose this to the domain 1. Discovered how thread works through contract tests 2. Use these tests to write a simulator like gmail 3. Very productive and con fi dent in implementing the domain logic
  33. Example : api change Both simulators and contract test shave

    been written to consume orange mails The application was tested with simulators Need to change end point used to read mails in the adapter (QOS issue) 1. Write the adapter with the new end point 2. Check the behavior still works as the old one and the simulator 3. Integrate the new end point safely without change neither domain code nor domain tests
  34. Example: remote fi le system (OneDrive) • Very slow, in

    particular for listing nested folders • There were around 15 methods on it • Having the fake made it very easy to implement a good caching system • As a result it was easy to implement both a persistent and an ephemeral caching system Storage OneDrive Slow
  35. Example: public company registry • Getting info about companies •

    Problem: not really. Read-only but stable • Solution: keep the exact assertions • In retrospect: They changed sometimes, but not often. Our app Data.gouv
  36. Example: data.entreprise.gouv • Getting (more) info about companies • Problem:

    Heteregenous data • Solution: Try ingesting big amounts of data as a test • Result: We discovered rare problems in dev as opposed to production Our app Data.gouv Heteregenous 
 data
  37. Example: Android system • A js-app running on android, it

    has a chatty api with a native app. • Problem: complex and wrong mocking • Solution: build a simulator (without contract testing) • Gain: Reliable tests of the isolated js-app js app native app Complex 
 interactions
  38. Example: Run tests on DB production • Warning : after

    the training • Running contract test in isolation as much as possible