Dependency injection is bad pattern used in OO languages to overcome weakness of these languages.
DI frameworks are very dangerous (they do many things under which you don’t have control of)
For this reason I will never use Angular
In Java the example of DI is Spring Framework

I was just trying to google something like that for you. Yes, behaviors is the fairly simple way to go and it’ll ensure the interface used in tests actually matches the one used in production (although the implementation differs).

And @mkunikow a lot of bad things can be said about mocks as well. My usual biggest concern is that you build the system that works in tests with mocks, but there can be mismatch between your mock’s interface and actual interface that you’ll miss and learn about it the hard way. Maintaining mocks, making sure everything’s mocked properly is also a considerable effort. It simply can be easier to build your own “null object” and pass it as a DI, or function parameter call it like you want, rather than trying to stub everything out.

Generally speaking, this question comes up a lot when people are coming from OO languages. @mkunikow makes a valid point that you don’t need it. The solution is fairly simple especially when it comes to testing. If you take the following steps, you won’t need to mock your functions that are touching the outside world.

Keep your impure functions separate from your pure functions. If you have a function that touches a database, calls a webservice, gets the date, etc. Or anything that touches the outside world it should be put in a separate module/function and there should be only one place in your program where it’s called and that data gets passed to your pure functions.

Your unit test will only need the stubbed data that would have come from an impure function like the data that would come from a webservice or a database.

The only time mocking is necessary is when you are calling impure functions from pure functions and they are intertwined (this is true even in OO languages). However, if you keep your impure functions separate from your pure functions then there is no need to have DI or a mocking framework when unit testing.

It presents several ways to “inject” dependencies to your functions, specifically by 1) defining the dependency module on your config, 2) passing the dependency’s handler function as the caller params, or 3) same as 2 but passing the dependency module altogether.

These three approaches allow you to use mock dependencies for your tests.

kostonstyle:

The problem is only the dynamic typing. How can I ensure, when someone use the function, that will pass the right module?

This article echoes José’s Plataformatec article I shared above on dependency injection methods, so I think you can use that as a base. The only thing it left out is for you to validate if a module has adopted a specific behavior. I’m not sure at the specifics on how to do that, though.

I’m surprised this topic didn’t spark any discussions around GenStage?

Personally, I’ve been using a pattern similar to Pact, but I have an item in the TODO list to properly learn and understand GenStage to decouple my system. Granted, it won’t solve your synchronous usecases, but I believe it’s worth a mention.