Just as an aside, white box testing (#2) shouldn&#x27;t be used for testing contracts between your inner interfaces, but rather, your consumption of some external interface that is hard to set up.<p>As an example, I want to make sure that when I hit a REST API endpoint, I do all my logic and get a proper return value (black box testing), maybe that the state of some bit that I&#x27;ve already set up is correctly changed (say, the database, by then checking it as part of the test to ensure the thing I said should be written was written), but that I also send a server sent event (SSE) to connected clients indicating the change. I don&#x27;t want to actually have to have opened up clients that conform to the SSE specification as part of my integ tests (because that&#x27;s a pain), so instead, I&#x27;ll just assert that the library call to send that event does indeed get called with the right thing. From there, I can test once, that the library call does indeed lead to an SSE being sent to the browser (and can even write a full environment integ test with Selenium or something), and from then on, my single system tests just assert that call is made when it&#x27;s supposed to. I&#x27;m effectively integration testing without implementing&#x2F;mocking a connected user to test SSEs.<p>Similar things can be useful when putting items onto external queues, making calls to foreign interfaces, etc. You should never make assertions about the path through your code a call takes in white box testing (because refactoring can change those, and you have increased your test burden for little reason), you should care about side effects you can&#x27;t easily otherwise test.