Fl4m3Ph03n1x

Fl4m3Ph03n1x

How to test a behaviour with function macros?

Background

I have a behaviour that has some functions inside it, so that modules that implement it can use them:

defmodule MyBehaviour do

  #some callback for other modules to implement
  @callback match(data :: any) :: boolean

  defmacro __using__(_opts) do

    quote do
      @behaviour MyBehaviour
      
      def build_query(some_str) do
        String.slice(some_str, 1..-1) #random op on string
      end

    end
  end
end

Problem

However, I need to test if build_query is working properly. I can’t invoke it and test it normally via MyBehaviour.build_query/1 because technically it doesn’t belong to the behaviour, it is instead inside the macro.

Question

How do I access MyBehaviour.build_query/1 in order to test it?

Marked As Solved

NobbZ

NobbZ

defmodule FooTest do
  defmodule FakeImplementor do
    use MyBehaviour
  end

  test "build the query" do
    # whatever is necessary to check `build_query/1` by calling it through `FakeImplementor`
  end
end

This is one way.

The other way (which I’d prefer) were to not inject it, but import it and also make it unimportable through options.

Also Liked

NobbZ

NobbZ

The default implementations are not tested at all, they just logg if they were called to avoid a spilling message queue, as soon as you see such a message in production, you should implement a proper handler that deals with those messages. If you have at least one handle_X, the default one isn’t used any more and your GenServer would crash on an unknown message for that handler.

child_spec is probably not tested as well, it just returns a constant map and doesn’t change.

If at all you’d test the __using__ macro if it creates the child_spec function correctly, as you need to specify some things that child_spec shall return as an argument to the use.

NobbZ

NobbZ

I’m not aware of the community opinion, but I hate everything that pollutes my namespace without giving me the option to surpress this polution.

I can cope with overridable default implementations, but for helper functions I prefer if they are in their own namespace.

But that is my personal opinion, the community might see it differently.

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement