jechol
Definject - Unobtrusive Dependency Injector for Elixir
Hello,
I just published version 1.1 of definject. It aims to make dependency injection unobtrusive.
import Definject
definject send_welcome_email(user_id) do
%{email: email} = Repo.get(User, user_id)
welcome_email(to: email)
|> Mailer.send()
end
is expanded into (simplified for understanding)
def send_welcome_email(user_id, deps \\ %{}) do
%{email: email} = Map.get(deps, &Repo.get/2, &Repo.get/2).(User, user_id)
welcome_email(to: email)
|> Map.get(deps, &Mailer.send/1, &Mailer.send/1).()
end
Then, you can inject mock functions and modules in tests.
test "send_welcome_email" do
Accounts.send_welcome_email(100, %{
Repo => MockRepo,
&Mailer.send/1 => fn %Email{to: "user100@gmail.com", subject: "Welcome"} ->
Process.send(self(), :email_sent)
end
})
assert_receive :email_sent
end
definject does not require you to modify function arguments or body. Instead, you just need to replace def with definject . It also allows injecting different mocks to each function. It also does not limit using :async option as mocks are contained in each test function.
You can find definject here:
https://github.com/chain-partners/definject
Thanks!
Most Liked
ityonemo
Typically with Mox you sub out the module name at compile time and at test time you bind in functions. This cleverly uses registry, $callers and $ancestors (I think) to make sure tests get isolated mocks.
With definject, the function is majorly fiddled with (basically rewritten) so that you don’t have to do that compile-time module substitution.
I would be worried that definject is more brittle and has more corner cases, but it’s the sort of thing where if it works for you it’ll work really well.
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








