# Testing an elixir function using Mock

**URL:** <https://forum.elixirforum.com/t/testing-an-elixir-function-using-mock/19429>\
**Category:** Questions\
**Tags:** phoenix, testing, learning-elixir, mocks\
**Created:** [January 16, 2019, 11:54am UTC](https://forum.elixirforum.com/t/testing-an-elixir-function-using-mock/19429 "2019-01-16T11:54:51Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![dimitarvp](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/32/38664_2.png) [@dimitarvp](https://forum.elixirforum.com/u/dimitarvp)\
**Post date:** [January 17, 2019, 4:46pm UTC](https://forum.elixirforum.com/t/testing-an-elixir-function-using-mock/19429/3 "2019-01-17T16:46:35Z")

</div>

First, here’s a stateful `Agent` that holds a counter and a simple logic that forces it to return the same value several times, before starting to return random values afterwards. Like this:

```elixir
defmodule NanoidMock do
  @moduledoc ~S"""
  Mocks Nanoid value producer with a simple counter.
  Initialize with `start_link(0)` to reproduce the following:
  For the first 4 invocations of `get_nano_id` the counter
  will move from 0 to 3 and will always return 0.
  After 4 invocations of `get_nano_id` (when the counter
  reaches 4) and onwards, it will return a random number.
  """

  use Agent

  # Initialize with a non-negative integer counter.
  def start_link(val) when val >= 0 do
    Agent.start_link(fn -> val end, name: __MODULE__ )
  end

  def stop(), do: Agent.stop( __MODULE__ )

  def clear(), do: Agent.update( __MODULE__ , fn(_) -> 0 end)

  def get_nano_id() do
    new_val = Agent.get_and_update( __MODULE__ , fn(x) -> {x, x + 1} end)
    case div(new_val, 4) do
      0 -> 0
      _ -> :rand.uniform(1_000_000)
    end
  end
end

```

* * *

Then let’s compose a test class:

```elixir
defmodule NanoidTestWithMock do
  def get_nano_id(), do: NanoidMock.get_nano_id()

  def upi_generate() do
    upi = "A#{get_nano_id()}C"

    case get_product_with_upi(upi) do
      nil -> upi
      _ -> upi_generate()
    end
  end

  defp get_product_with_upi(upi) do
    case upi do
      "A0C" ->
        IO.puts "Duplicated UPI=A0C. Retrying."
        %{error: "product already exists"}

      _ ->
        nil
    end
  end

  def test() do
    NanoidMock.start_link(0)
    upi = upi_generate()
    NanoidMock.stop()
    IO.puts "Successfuly got unique UPI=#{upi}"
  end
end

```

* * *

Put these modules in a single Elixir file and then run `NanoidTestWithMock.test()` in an `iex` session.

(Or add the above expression at the bottom of the file and just tell Elixir to run it.)

You should see something like this:

```elixir
Duplicated UPI=A0C. Retrying.
Duplicated UPI=A0C. Retrying.
Duplicated UPI=A0C. Retrying.
Duplicated UPI=A0C. Retrying.
Successfuly got unique UPI=A394747C

```

Hope that helps.

_EDIT: As for mocking the Nanoid library itself, I’ll leave that exercise to you._

---

_[View the full topic](https://forum.elixirforum.com/t/testing-an-elixir-function-using-mock/19429)._
