Assert that a particular function was called

I have a function that will randomly select a string from a list, the string in the list is also a function name. When the function name is selected from the list I then have a function that will call the selected function. To make this more clear I’ll post some code:

CODE:

  @questions ["Total Player Points", "Total Player Rebounds"]

  def total_player_points(description) do
    qualified_player()
    |> initialize_question(description)
    |> create_question
  end

  def total_player_rebounds(description) do
    qualified_player()
    |> initialize_question(description)
    |> create_question
  end

  def pick_question do
    question =
      Enum.random(@questions)
      apply(String.to_existing_atom("#{__MODULE__}"), string_to_function(question), [question])
  end

  defp string_to_function(string) do
    string
    |> String.downcase()
    |> String.split()
    |> Enum.join("_")
    |> String.to_atom()
  end

Okay, I’d like to test that one of the functions, either total_player_points or total_player_rebounds were called. I don’t want to actually run those function in my test because I already have those tested in other places, I just want to ensure that one of them were called at all. How can I achieve this? I’ve seen people talk about this mock library in other treads but I haven’t been able to find what I’m looking for.

Again, I’d like to assert that one of the functions were called, either total_player_points or total_player_rebounds

I also know that both of those functions are doing the same thing and I could easily extract them into one function, I’m intentionally not doing that at the moment because this module is going to grow and that wont be an option in the future. Thanks for your help!

I usually like to pull side effects (randomness in this case) to the highest level I can and pass it in as a dependency. In this case, I’d write pick_question like so:

  def pick_question(question \\ Enum.random(@questions)) do 
    apply(String.to_existing_atom("#{__MODULE__}"), string_to_function(question), [question])
  end

Then, it’s pretty easy to test both cases, by just calling pick_question("Total Player Points") and pick_question("Total Player Rebounds"). I wouldn’t worry so much about whether a particular function is called. Instead I’d validate that the return value had the expected description. I’d probably also make the first two functions private and only test through pick_question.

2 Likes