|
Dependency inversion does apply sometimes, but a well-designed library caps async around functions that need it - things that interact with filesystem or network, etc. Those are perfectly testable as-is. Your core business logic is still sync, if you'd like to to be. Async can call sync just fine, and sync can call async, as long as you are willing to admit that you're abstracting away a network call in a unit tests (for some reason). The typical pattern I enjoy is: * Sync for the logic * Async for the job runners b/c I'd like to do other things while it's going. * Sync or Async as required for the data wrangling (db calls, network, filesystem) So you have essentially: 1. kick off job, returning a future, by calling an async function. 2. Job is mostly async data wrangling, followed by a sync logic block that's unit tested, followed by an async "save" if required. 3. Either wait for the future, or run the task in the background, or `.await` if you're in an async block. I'm hand waving away the syntax, but that's the mental model. 99% of code isn't async, and the code that is isn't async for the fun of it. |