Integration testing is hard

Yes, and add sleeps to wait for the insert, which is undesirable. I don’t want to mock the database, I want to know when it has performed its tasks.

This looks like an actual fallacy namely circular reasoning:

  1. You need a behavior because without one, it’s hard to test stuff
  2. When it’s hard to test stuff, you need a behavior

Example

  • There is a process A that generates telemetry as a side effect
  • There is a module that subscribes to this telemetry and casts it to process B
  • Process B holds some state that can lead to events being filtered. This is strongly tied what events generated by A look like
  • Process B saves the events to a database

Of course I can test separately whether

  • A generates the correct telemetry
  • Telemetry leads to a cast
  • Make the functions in B public and test whether they result in the correct database records

That also means

  • Copying the telemetry content across tests, because we need to test whether A sends it correctly, and then use it as input for B
  • Making a factory for the above
  • Or more likely, certain events will not be tested fully

While your other points are well taken I don’t see a solution for an end-to-end test of the above that doesn’t involve sleeps.