I’m currently writing some tests for a DynamicSupervisor. The children started by this supervisor connect to a database and make a couple HTTP calls in their
handle_continue callback. I tried to use Ecto.Adapters.SQL.Sandbox and Bypass to mock these calls, however this created a lot of headaches on my side. As I’m only interested in the custom behavior of my DynamicSupervisor in these tests, (the child genserver have their own tests of course), I wanted to know if there is some way to start a process and immediately suspend it. This way could just test the supervisor without mocking the database and HTTP calls.
I would probably change my code so that the specific child specification that gets started by the supervisor can be passed in the test (maybe defaulting to the correct production specifications). This way, in your test you can have the
DynamicSupervisor start a test child without the complexity of sandboxing or mocking.
Yeah this could work, however I’m not a fan of increasing the complexity of code just for testing purposes.
Maybe there is a way to start a process and manually handle its lifetime step by step.
My two cents: I would consider this into the category of designing the API of your modules so that they are testable. If you cannot pass the child specs, then it is a private implementation detail, and you should rather test the outside observable effects (which requires either setting up a database, or mocking it). Conversely, if you want to unit-test it in isolation from the database, the unit should not hardcode the database part, and rather allow passing it in its API.