Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tlux/delx
Defdelegate on steroids! An Elixir library to make function delegation testable.
https://github.com/tlux/delx
assertions defdelegate delegated-functions elixir elixir-library hex-package mox
Last synced: 5 days ago
JSON representation
Defdelegate on steroids! An Elixir library to make function delegation testable.
- Host: GitHub
- URL: https://github.com/tlux/delx
- Owner: tlux
- License: mit
- Created: 2019-05-15T13:38:33.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-11-07T15:06:08.000Z (about 2 years ago)
- Last Synced: 2024-10-29T08:41:15.928Z (19 days ago)
- Topics: assertions, defdelegate, delegated-functions, elixir, elixir-library, hex-package, mox
- Language: Elixir
- Homepage:
- Size: 58.6 KB
- Stars: 3
- Watchers: 11
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Delx
[![Build Status](https://travis-ci.org/tlux/delx.svg?branch=master)](https://travis-ci.org/tlux/delx)
[![Coverage Status](https://coveralls.io/repos/github/tlux/delx/badge.svg?branch=master)](https://coveralls.io/github/tlux/delx?branch=master)
[![Hex.pm](https://img.shields.io/hexpm/v/delx.svg)](https://hex.pm/packages/delx)[Defdelegate](https://hexdocs.pm/elixir/Kernel.html#defdelegate/2) on steroids!
An Elixir library to make function delegation testable.## Prerequisites
- Erlang 20 or greater
- Elixir 1.8 or greater## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `delx` to your list of dependencies in `mix.exs`:```elixir
def deps do
[
{:delx, "~> 3.0"}
]
end
```## Usage
Check out the full docs at [https://hexdocs.pm/delx](https://hexdocs.pm/delx).
Let's say you have the following module.
```elixir
defmodule Greeter.StringGreeter do
def hello(name) do
"Hello, #{name}!"
end
end
```You can delegate functions calls to another module by using the `Delx` module
and calling the `defdelegate/2` macro in the module body. It has the same API as
Elixir's own `Kernel.defdelegate/2` macro.```elixir
defmodule Greeter do
use Delx, otp_app: :greeterdefdelegate hello(name), to: Greeter.StringGreeter
endGreeter.hello("Tobi")
# => "Hello, Tobi!"
```## Testing
One great benefit of Delx is that you can test delegation without invoking
the actual implementation of the delegation target, thus eliminating all side
effects.### Built-In Assertions
Delx brings it's own test assertions.
All you need to do is to activate delegation mocking for your test environment
by putting the following line in your `config/test.exs`:```elixir
config :greeter, Delx, mock: true
```Then in your tests, you can import `Delx.TestAssertions` and use the
`assert_delegate/2` and `refute_delegate/2` assertions.```elixir
defmodule GreeterTest do
use ExUnit.Caseimport Delx.TestAssertions
describe "hello/1" do
test "delegate to Greeter.StringGreeter" do
assert_delegate {Greeter, :hello, 1}, to: Greeter.StringGreeter
end
end
end
```Note that once you activate mocking all delegated functions do not return
anymore but instead raise the `Delx.MockedDelegationError`. If you really
want to call the original implementation, you have to avoid any calls of
delegated functions.### With Mox
If you are using [Mox](https://hexdocs.pm/mox) in your application you have
another possibility to test delegated functions.Register a mock for the `Delx.Delegator` behavior to your
`test/test_helper.exs` (or wherever you define your mocks):```elixir
Mox.defmock(Greeter.DelegatorMock, for: Delx.Delegator)
```Then, in your `config/test.exs` you have to set the mock as delegator module
for your app.```elixir
config :my_app, Delx, delegator: Greeter.DelegatorMock
```Please make sure not to use the `:mock` option and a `:delegator` option at the
same time as this may lead to unexpected behavior.Now you are able to `expect` calls to delegated functions:
```elixir
defmodule GreeterTest do
use ExUnit.Caseimport Mox
setup :verify_on_exit!
describe "hello/1" do
test "delegate to Greeter.StringGreeter" do
expect(
Greeter.DelegatorMock,
:apply,
fn {Greeter, :hello},
{Greeter.StringGreeter, :hello},
["Tobi"] ->
:ok
end
)Greeter.hello("Tobi")
end
end
end
```For more information on how to implement your own delegator, refer to the
docs of the `Delx.Delegator` behavior.Note that the configuration is only applied at compile time, so you are unable
to mock or replace the delegator module at runtime.## Migration from v2 to v3
Note that the function `defdel/2` has been removed in favor of `defdelegate/2`
to give a better experience with the tooling. Additionally, let's say you want
to migrate away from Delx you can simply un`use` Delx to fall back to the
default `Kernel.defdelegate/2` and your code will still work.The config option to enable testing mode has changed from `stub` to `mock`. If
you got the following line in your config:```elixir
config :greeter, Delx, stub: true
```Please change it to:
```elixir
config :greeter, Delx, mock: true
```