<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lasse Skindstad Ebert</title>
    <description>The latest articles on DEV Community by Lasse Skindstad Ebert (@lasseebert).</description>
    <link>https://dev.to/lasseebert</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F225966%2Facbac297-5cd2-48c9-b853-d6ba193a4788.jpeg</url>
      <title>DEV Community: Lasse Skindstad Ebert</title>
      <link>https://dev.to/lasseebert</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lasseebert"/>
    <language>en</language>
    <item>
      <title>TIL: Unicode chars in regex</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Fri, 25 Oct 2019 06:40:37 +0000</pubDate>
      <link>https://dev.to/lasseebert/til-unicode-chars-in-regex-1m9a</link>
      <guid>https://dev.to/lasseebert/til-unicode-chars-in-regex-1m9a</guid>
      <description>&lt;p&gt;Today I needed to match some unicode chars in an Elixir regex.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR:
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;u&lt;/code&gt; modifier and &lt;code&gt;\x{...}&lt;/code&gt;, e.g. &lt;code&gt;~r/\x{1234}/u&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Matching a unicode char in a regex
&lt;/h2&gt;

&lt;p&gt;More specifically, I needed to remove all zero width chars from a string.&lt;br&gt;
These are &lt;code&gt;U+200B&lt;/code&gt;, &lt;code&gt;U+200C&lt;/code&gt;, &lt;code&gt;U+200D&lt;/code&gt; and &lt;code&gt;U+FEFF&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Trying to use &lt;code&gt;\u&lt;/code&gt; does not work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt; ~r/\u200B/
** (Regex.CompileError) PCRE does not support \L, \l, \N{name}, \U, or \u at position 1
    (elixir) lib/regex.ex:209: Regex.compile!/2
    (elixir) expanding macro: Kernel.sigil_r/2
    iex:1: (file)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Looking at &lt;a href="http://erlang.org/doc/man/re.html"&gt;the docs&lt;/a&gt;, it seems that &lt;code&gt;\x{}&lt;/code&gt; is the way to go, but no:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt; ~r/\x{200B}/
** (Regex.CompileError) character value in \x{} or \o{} is too large at position 7
    (elixir) lib/regex.ex:209: Regex.compile!/2
    (elixir) expanding macro: Kernel.sigil_r/2
    iex:1: (file)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The trick is that we need to &lt;a href="https://hexdocs.pm/elixir/1.9.2/Regex.html#module-modifiers"&gt;apply a &lt;code&gt;unicode&lt;/code&gt; (&lt;code&gt;u&lt;/code&gt;) modfier&lt;/a&gt; to the regex, telling the regex compiler that we're working in Unicode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt; ~r/\x{200B}/u
~r/\x{200B}/u
iex(2)&amp;gt; "Hello,\u200BWorld!" |&amp;gt; String.replace(~r/\x{200B}/u, "")    
"Hello,World!"

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yay!&lt;/p&gt;

&lt;p&gt;So my final regex could be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="sr"&gt;~r/\x{200B}|\x{200C}|\x{200D}|\x{FEFF}/u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Interpolation works too.
&lt;/h2&gt;

&lt;p&gt;We can also interpolate strings into a regex, which works the same way and works without the &lt;code&gt;u&lt;/code&gt; modifer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(5)&amp;gt; "Hello,\u200BWorld!" |&amp;gt; String.replace(~r/#{"\u200B"}/, "")
"Hello,World!"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>elixir</category>
      <category>regex</category>
    </item>
    <item>
      <title>Enum.map_reduce/3</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Tue, 22 Oct 2019 11:52:53 +0000</pubDate>
      <link>https://dev.to/lasseebert/enum-mapreduce-3-3n55</link>
      <guid>https://dev.to/lasseebert/enum-mapreduce-3-3n55</guid>
      <description>&lt;p&gt;Today I found a function in Elixir's standard lib that I have often needed.&lt;/p&gt;

&lt;p&gt;Introducing: &lt;code&gt;Enum.map_reduce/3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Enum.map_reduce/3&lt;/code&gt; can replace &lt;code&gt;Enum.reduce/3&lt;/code&gt; when the &lt;code&gt;reduce&lt;/code&gt; maps each element to another element and we also want to maintain some state or build a result along the way.&lt;/p&gt;

&lt;p&gt;This might be a bit cryptic, so let's start with an example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a cache while mapping
&lt;/h2&gt;

&lt;p&gt;Let's pretend I don't know about &lt;code&gt;Enum.map_reduce/3&lt;/code&gt; and I need to map a list of numbers to the maximum of the number and the previous number.&lt;/p&gt;

&lt;p&gt;I would do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;_last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;(Ok, this simple example could also be solved nicely with &lt;code&gt;Enum.chunk_every/2&lt;/code&gt; and &lt;code&gt;Enum.map/2&lt;/code&gt;, but for the sake of example let's play with this)&lt;/p&gt;

&lt;p&gt;This will give the expected result &lt;code&gt;[5, 5, 8, 9, 9, 2, 7, 7]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Notice that I need to reverse the number list at the end, since I append numbers to the start of the list.&lt;/p&gt;

&lt;p&gt;If only there is a way to do this in a smarter way...&lt;/p&gt;

&lt;p&gt;Well, with &lt;code&gt;Enum.map_reduce/3&lt;/code&gt; we can do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_last&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So here we use &lt;code&gt;map_reduce&lt;/code&gt;'s accumulator to remember what the last number was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a result while mapping
&lt;/h2&gt;

&lt;p&gt;We can also use it to accumulate something we need as a result while we're mapping a list.&lt;/p&gt;

&lt;p&gt;Perhaps we want to know the largest number while doing the max-thing above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_last&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which will give the same &lt;code&gt;numbers&lt;/code&gt; as before, but now we also get &lt;code&gt;9&lt;/code&gt; as the max item.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enum.flat_map_reduce
&lt;/h2&gt;

&lt;p&gt;In the cases where each iteration might yield zero or many items to the resulting list, we can use &lt;code&gt;Enum.flat_map_reduce/3&lt;/code&gt;. This works like &lt;code&gt;Enum.map_reduce/3&lt;/code&gt; with two differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each iteration must yield a list of elements instead of a single element. Notice that we can use an empty list if an iteration should not add something to the resulting list.&lt;/li&gt;
&lt;li&gt;It is possible to break early using &lt;code&gt;:halt&lt;/code&gt;, almost like with &lt;code&gt;Enum.reduce_while/3&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: We want to map a list to another list where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All odd numbers are removed&lt;/li&gt;
&lt;li&gt;All even numbers are doubled&lt;/li&gt;
&lt;li&gt;We want to sum the original numbers&lt;/li&gt;
&lt;li&gt;If we hit 7, we stop
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flat_map_reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:halt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{[],&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which will give &lt;code&gt;{[2, 2, 8, 8, 2, 2], 27}&lt;/code&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
    </item>
    <item>
      <title>TIL: Ecto's pin is coercing</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Mon, 21 Oct 2019 12:45:48 +0000</pubDate>
      <link>https://dev.to/lasseebert/til-ecto-s-pin-is-coercing-19fh</link>
      <guid>https://dev.to/lasseebert/til-ecto-s-pin-is-coercing-19fh</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;is &lt;em&gt;not&lt;/em&gt; the same as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"42"&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the latter case, the value &lt;code&gt;"42"&lt;/code&gt; is coerced to the integer &lt;code&gt;42&lt;/code&gt; (if the &lt;code&gt;owner_id&lt;/code&gt; of an account is an integer according to the Ecto schema).&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Today I found a bug in some code I wrote a long time ago.&lt;/p&gt;

&lt;p&gt;The code was supposed to take a map of &lt;code&gt;atom =&amp;gt; String.t&lt;/code&gt; and convert some of the values to integers. But it didn't. And my other code dependent on this still ran without errors!&lt;/p&gt;

&lt;p&gt;Time to pick up the Sherlock Holmes monocle and find out why this bug never yielded an actual error.&lt;/p&gt;

&lt;p&gt;It turns out I later used the value like so in Ecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;owner_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The account's &lt;code&gt;owner_id&lt;/code&gt; is an integer, but I try to compare it with a string, because of the above bug. And it does not fail!?&lt;/p&gt;

&lt;p&gt;I opened up an iex and tried this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; Account |&amp;gt; where([account], owner_id: "42") |&amp;gt; Repo.all()
** (Ecto.QueryError) iex:2: value `"42"` cannot be dumped to type :id.
   Or the value is incompatible or it must be interpolated (using ^) so it may be cast
   accordingly in query:

from a0 in Account,
  where: a0.owner_id == "42",
  select: a0

    (elixir) lib/enum.ex:1440: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3 
    (elixir) lib/enum.ex:1440: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
    (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This fails. Ah, finally some sanity :)&lt;/p&gt;

&lt;p&gt;The error message also suggests that I might need a pin operator to interpolate the value. So I tried this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; Account |&amp;gt; where([account], owner_id: ^"42") |&amp;gt; Repo.all()
[]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And this is why my code did not fail. It was simply ignoring that I had to do with a string and coerced it into a integer.&lt;/p&gt;

&lt;p&gt;I thought the pin-operator was only for inserting values of variables, but now I know it also acts as a coercer (or interpolator).&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>ecto</category>
    </item>
    <item>
      <title>TIL: Understanding dialyzer’s “The pattern can never match the type.”</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 19:49:52 +0000</pubDate>
      <link>https://dev.to/lasseebert/til-understanding-dialyzer-s-the-pattern-can-never-match-the-type-2mmm</link>
      <guid>https://dev.to/lasseebert/til-understanding-dialyzer-s-the-pattern-can-never-match-the-type-2mmm</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2019-09-03, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I like dialyzer and typespecs. They are a natural part of my TDD flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write a failing test&lt;/li&gt;
&lt;li&gt;Write docs for function&lt;/li&gt;
&lt;li&gt;Write typespecs for function&lt;/li&gt;
&lt;li&gt;Write the function&lt;/li&gt;
&lt;li&gt;See that test is now green&lt;/li&gt;
&lt;li&gt;Refactor&lt;/li&gt;
&lt;li&gt;See that test is still green&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having written tests, docs and a spec for a function, makes it much more clear what the function should accept as arguments and what it should return. I also tend to write more reusable functions with this flow.&lt;/p&gt;

&lt;p&gt;The typespecs will also function as documentation when reading the function.&lt;/p&gt;

&lt;p&gt;But dialyzer has a downside. Debugging dialyzer warnings can be a real pain and it is often not clear where to look for a wrong typespec or whatever made dialyzer vomit all over my terminal with less-than-obvious messages.&lt;/p&gt;

&lt;p&gt;I spend a good three hours today debugging a dialyzer warning in my Elixir app, so I’m naturally obligated to share my insights with the world :)&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;I got an error in a with statement much like this one in function &lt;code&gt;c/0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;DialyzerTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:another_error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:another_error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
         &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="ss"&gt;:ok&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The dializer warning says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;simple_dialyzer_test.ex:14:pattern_match
The pattern can never match the type.

Pattern:
:error

Type:
:another_error
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is a pretty light-weight warning compared to dialyzer standards. Normally I need to copy-paste the message into an editor to format it and be able to make a little sense out of it.&lt;/p&gt;

&lt;p&gt;So apparently &lt;code&gt;:error&lt;/code&gt; does not match &lt;code&gt;:another_error&lt;/code&gt;, which is obvious, but why complain about it? When I wrote the code, I called &lt;code&gt;b/0&lt;/code&gt; in a way that shouldn’t make it return anything else than &lt;code&gt;:ok&lt;/code&gt;, so I would like a runtime exception if anything else is returned from that function.&lt;/p&gt;

&lt;p&gt;My mistake was that I considered the above example the same as this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;DialyzerTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:another_error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:another_error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="ss"&gt;:ok&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that we only match on &lt;code&gt;:ok&lt;/code&gt; and &lt;code&gt;:error&lt;/code&gt;, but not on &lt;code&gt;:another_error&lt;/code&gt;. This code does not produce a dialyzer warning.&lt;/p&gt;

&lt;p&gt;What the hell is going on?&lt;/p&gt;

&lt;p&gt;After a long time of debugging and trying to find a wrong typespec, I realized how dialyzer handles with: For each statement in the &lt;code&gt;with&lt;/code&gt; (all the lines with &lt;code&gt;a &amp;lt;- b&lt;/code&gt;), we can think of it as “&lt;code&gt;b&lt;/code&gt; must either match &lt;code&gt;a&lt;/code&gt; or must match at least one clause in &lt;code&gt;else&lt;/code&gt;”.&lt;/p&gt;

&lt;p&gt;I tried digging deeper in the elixir source code to get a confirmation of this, but &lt;code&gt;with&lt;/code&gt; is a special form and implemented in dark magic, so I got no further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution?
&lt;/h2&gt;

&lt;p&gt;Yes, there is an easy solution. If you don’t want the statement in the &lt;code&gt;with&lt;/code&gt; to match anything in &lt;code&gt;else&lt;/code&gt;, don’t include the statement in the &lt;code&gt;with&lt;/code&gt;. You can include it before, after or inside &lt;code&gt;do&lt;/code&gt;, whateever fits the use case.&lt;/p&gt;

&lt;p&gt;In my small example from the top, I would simply rewrite, so that the call to &lt;code&gt;b/0&lt;/code&gt; was moved inside the &lt;code&gt;do&lt;/code&gt; and matched with the expected return value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And since I now only have a single statement in the &lt;code&gt;with&lt;/code&gt;, I would probably refactor to a &lt;code&gt;case&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="ss"&gt;:ok&lt;/span&gt;

    &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Again, dialyzer was right. It does not make sense to have a statement inside a &lt;code&gt;with&lt;/code&gt; if I’m never going to match a clause in &lt;code&gt;else&lt;/code&gt; with it. My code is now easier to read, since it is obvious to the reader that &lt;code&gt;b/0&lt;/code&gt; &lt;em&gt;must&lt;/em&gt; return &lt;code&gt;:ok&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>dialyzer</category>
    </item>
    <item>
      <title>Embedded Elixir (without Nerves)</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 19:39:29 +0000</pubDate>
      <link>https://dev.to/lasseebert/embedded-elixir-without-nerves-69h</link>
      <guid>https://dev.to/lasseebert/embedded-elixir-without-nerves-69h</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2018-08-29, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I love Nerves. Unfortunately I am in a situation where I can not use it for my current project.&lt;/p&gt;

&lt;p&gt;This is a somewhat detailed guide on how to run Elixir on an embedded linux without using Nerves.&lt;/p&gt;

&lt;h2&gt;
  
  
  My use case
&lt;/h2&gt;

&lt;p&gt;I am a co-founder and a backender of Wise Home, a company located in Denmark. We do smart-home stuff for rental buildings. Our hardware pusher provides a small linux-box, which we call a gateway.&lt;/p&gt;

&lt;p&gt;The gateway comes with some software used to communicate with external devices. This is provided as a modified buildroot with the hardware pusher’s custom patches and software. Buildroot is a tool that can build linux images, mostly used for embedded devices.&lt;/p&gt;

&lt;p&gt;I can put my extra software on the gateway by modifiying that buildroot configuration, but it would be hard (maybe impossible?) to put their software and patches on my own buildroot config, which is why I can not use Nerves.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add Erlang to a buildroot configuration?
&lt;/h2&gt;

&lt;p&gt;The linux image that is the output of running buildroot must contain everything needed to run the gateway. This is because most of the file system is read-only, because the gateway should not be able to get to a state where it can’t just reboot and everything is fine again.&lt;/p&gt;

&lt;p&gt;This means that we have to put Erlang on the linux image. The gateway runs an ARM processor, so we must cross-compile Erlang to ARM. The heavy work of this is done by buildroot, so we can just configure it to install Erlang.&lt;/p&gt;

&lt;p&gt;The buildroot configuration I’m locked to is outdated and contains an old Erlang config, but luckily I was able to just pull &lt;a href="https://github.com/buildroot/buildroot/tree/master/package/erlang"&gt;the latest Erlang config&lt;/a&gt; into my own buildroot without any trouble.&lt;/p&gt;

&lt;p&gt;From here it is just a matter of selecting Erlang when configuring buildroot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s5bjypy---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/r8au5keinv2y4zl4dpt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s5bjypy---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/r8au5keinv2y4zl4dpt8.png" alt="Selecting erlang in the buildroot config tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Buildroot will now do the heavy lifting of actually cross-compiling Erlang and add it to my linux image.&lt;/p&gt;

&lt;p&gt;If you have never used buildroot before and want to use it, I recommend spending a little time on &lt;a href="https://buildroot.org/downloads/manual/manual.html#_getting_started"&gt;their guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  So how is Elixir installed, then?
&lt;/h2&gt;

&lt;p&gt;I thought I needed to also do some cross-compiling for Elixir, but I had two eureka-moments when investigating this.&lt;/p&gt;

&lt;p&gt;First of, Elixir does not have any native executables. An Elixir installation is basically a bunch of bash-scripts and some beam-files. The bash-scripts starts Erlang and the beam-files are Elixir compiled into BEAM-code.&lt;/p&gt;

&lt;p&gt;Secondly, Elixir (the beam files compiled from Elixir) is already included when making a release with &lt;a href="https://github.com/bitwalker/distillery"&gt;Distillery&lt;/a&gt;. It is actually “just” a library sitting there with all the other included libraries:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mABjl2Ee--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jftlggff4l2twwdmqodi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mABjl2Ee--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jftlggff4l2twwdmqodi.png" alt="Listing included libraries from a Distillery release"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that if we can deploy a Distillery release of our app onto the linux image, we’re golden. So that’s up next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying a Distillery release to the linux image
&lt;/h2&gt;

&lt;p&gt;The only non-default configuration I made to my Distillery build was to not include ERTS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="ss"&gt;:balrog&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;version:&lt;/span&gt; &lt;span class="n"&gt;current_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:balrog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;include_erts:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
  &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;include_src:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ERTS is the Erlang runtime (Erlang Run-Time System) and that is what we needed to cross compile. When not including ERTS in the release, we must make sure that the Erlang version used to build the release is exactly the same as on the target linux image.&lt;/p&gt;

&lt;p&gt;Normally when I “deploy” stuff it means that I build a release which is uploaded to a server. With embedded devices, we need to include it in the linux image before it is booting up for the first time.&lt;/p&gt;

&lt;p&gt;With buildroot, we can simply add files to the file system of the linux box. This is called “rootfs overlay”. For convenience, I made a small script that builds the release and unpacks the resulting tar onto my rootfs overlay.&lt;/p&gt;

&lt;p&gt;After the next buildroot build, it will be contained in my linux image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the release on a read-only file system
&lt;/h2&gt;

&lt;p&gt;By now, I thought I was done. But no. The Distillery release expects by default the file system to be read-write, but on an embedded linux, most of the file system is read-only.&lt;/p&gt;

&lt;p&gt;The first attempt to run the release resulted in an error message saying that the log file folder could not be made.&lt;/p&gt;

&lt;p&gt;It turns out that &lt;a href="https://github.com/bitwalker/distillery/blob/master/priv/libexec/env.sh"&gt;a lot of environment variables&lt;/a&gt; can affect how a release is started. I ended up using these four in a winning combo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PIDFILE&lt;/code&gt;: On the gateway there is a monitoring system called monit. It expects each monitored application to write its own process-id to a file. With PIDFILE we tell Distillery where that file should be located.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LC_ALL=en_US.UTF-8&lt;/code&gt;: Not really Erlang or Elixir specific, but Elixir complained if Erlang was not run with UTF-8. I added the &lt;code&gt;en_US.UTF-8&lt;/code&gt; locale via buildroot and select to use it with this env var.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RELEASE_MUTABLE_DIR&lt;/code&gt;: This is the env var that saved my day. I can tell distillery where all mutable files can be located. On my gateway the &lt;code&gt;/data&lt;/code&gt; dir was read-write, so I chose a subdir of that.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HOME&lt;/code&gt;: Again, not specific to Erlang, but Erlang tries to save a cookie file in the home dir for some reason. Since the home dir in my case was read-only, I set it to something else when running the release.&lt;/p&gt;

&lt;p&gt;All in all, this is the command I ended up with that worked nicely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HOME=/data/balrog/ \
RELEASE_MUTABLE_DIR=/data/balrog/ \
LC_ALL=en_US.UTF-8 \
PIDFILE=/tmp/balrog.pid \
/balrog/bin/balrog start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yes, my app is called Balrog. Don’t ask. I might do a post later on naming things, which is of course the hardest thing in computer science.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further reading and investigation
&lt;/h2&gt;

&lt;p&gt;I found a lot of interesting and useful things on my way to deploy Elixir on an embedded linux.&lt;/p&gt;

&lt;p&gt;Things I can recommend to investigate:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Buildroot&lt;/strong&gt;. This is a good tool to know if you do anything on embedded devices. E.g. if you use Nerves and need to modify which applications and libraries are installed on the linux image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distillery&lt;/strong&gt;. It goes without saying that this is an important tool in Elixir-land. But don’t just read the documentation. I found a lot of useful stuff in comments in the codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your filesystem&lt;/strong&gt;. I found a lot of clarification by looking at my local Elixir installation and the Distillery release generated from my application. Browse though the directories and peak inside the bash scripts.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>embedded</category>
    </item>
    <item>
      <title>Isolating code in contexts</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 19:17:15 +0000</pubDate>
      <link>https://dev.to/lasseebert/isolating-code-in-contexts-102c</link>
      <guid>https://dev.to/lasseebert/isolating-code-in-contexts-102c</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2017-12-15, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This blog post is about a design pattern that I know as “The Context Pattern”.&lt;/p&gt;

&lt;p&gt;I am a software developer and my key focus is writing maintainable software. This is why I love software patterns. Patterns allow me to reason about my software on a more abstract level and they force me to write maintainable software from day one of a new project.&lt;/p&gt;

&lt;p&gt;I use Elixir to illustrate my points, but I think the pattern can be adapted to most programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  History of The Context Pattern
&lt;/h2&gt;

&lt;p&gt;I like to think of The Context Pattern as a specialized form of &lt;a href="https://en.wikipedia.org/wiki/Facade_pattern"&gt;The Facade Pattern&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Facade pattern evolved in object oriented languages and was probably first formalized by the &lt;a href="https://en.wikipedia.org/wiki/Design_Patterns"&gt;Gang Of Four&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Context Pattern differs from The Facade Pattern in that it always isolates internal (not external) code, hiding away its complexity from the caller. It also isolates source code files in the file system from the rest of the code base.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://phoenixframework.org"&gt;Phoenix framework&lt;/a&gt; &lt;a href="https://hexdocs.pm/phoenix/contexts.html#content"&gt;called the pattern name&lt;/a&gt; with the release of Phoenix 1.3. Although Phoenix contexts are kind of Phoenix specific, I am using the pattern for non-Phoenix code too.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is it, exactly?
&lt;/h2&gt;

&lt;p&gt;Disclaimer: This is my version of The Context Pattern. I’m not sure if the pattern has been formalized for general usage by anyone.&lt;/p&gt;

&lt;p&gt;The pattern is simple and yet extremely powerful. You only have to do these steps to follow the pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find code in your code base that belong together, i.e. has many internal dependencies.&lt;/li&gt;
&lt;li&gt;Move all code files into a specific directory in your project directory. Rename namespaces accordingly.&lt;/li&gt;
&lt;li&gt;Define a single entry point of all the functionality the code exposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new group of code is then conceptually referred to as “context”.&lt;/p&gt;

&lt;p&gt;This gives the immediate benefit of simplicity for the outside world. All the code &lt;em&gt;not&lt;/em&gt; in the context only have to worry about the public API of the context, which is all defined in a single entry point.&lt;/p&gt;

&lt;p&gt;Changing stuff later inside the context is now also simple. Everything can be changed as long as the public API remains unchanged.&lt;/p&gt;

&lt;p&gt;While writing a context or refactoring existing code into a context, the concept of a context makes the developer worry about dependencies and interfaces. Only the needed amount is exposed to outside code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example time
&lt;/h2&gt;

&lt;p&gt;Finally some code.&lt;/p&gt;

&lt;p&gt;A while ago, I had to implement geolocation lookup functionality in an existing project. For a given city, I needed to know the lattitude and longitude coordinates.&lt;/p&gt;

&lt;p&gt;I needed the following parts to complete the feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A client that can talk to the Google Maps API&lt;/li&gt;
&lt;li&gt;A database model for long-term caching the API lookup&lt;/li&gt;
&lt;li&gt;A cache with logic to operate on the database model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could probably write it all in one Elixir module, but that would be a big mess. It would not be testable and maintainable.&lt;/p&gt;

&lt;p&gt;Furthermore, I needed different implementations of the client HTTP layer, since I wanted to &lt;a href="https://dev.to/lasseebert/mocks-in-elixir-19a4"&gt;swap it out with a mock when testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I ended up with the following directory structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/my_project/geolocation
├── cache.ex
├── city_location.ex
├── geolocation.ex
└── google_maps
    ├── client.ex
    ├── http.ex
    └── http_mock.ex
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The only thing that the outside code should call is the MyProject.Geolocation module which is in the file &lt;code&gt;lib/my_project/geolocation/geolocation.ex&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All the other modules are namesspaced under &lt;code&gt;Geolocation&lt;/code&gt;, e.g. &lt;code&gt;MyProject.Geolocation.Cache&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Geolocation&lt;/code&gt; module has a single function with this signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;geolocation&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;longitude&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
Finds the geolocation for the given address
"""&lt;/span&gt;
&lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# Logic that calls the inner modules&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  What about OTP and GenServers?
&lt;/h2&gt;

&lt;p&gt;I’m glad you asked :) The Cache in the example is actually a GenServer to synchronize cache lookups and avoid race situations.&lt;/p&gt;

&lt;p&gt;So how does the main application know to start the Cache when it is not allowed to peak inside the context?&lt;/p&gt;

&lt;p&gt;Elixir 1.5 to the rescue!&lt;/p&gt;

&lt;p&gt;Elixir 1.5 introduced &lt;a href="https://github.com/elixir-lang/elixir/blob/v1.5/CHANGELOG.md#streamlined-child-specs"&gt;streamlined child specs&lt;/a&gt;, which allows any module to define a child spec, and that module can be added by itself to a supervisor.&lt;/p&gt;

&lt;p&gt;That was a confusing explanation, so here is an example:&lt;/p&gt;

&lt;p&gt;Instead of adding &lt;code&gt;worker(MyProject.Geolocation.Cache, [])&lt;/code&gt; as a child to my main supervisor, with Elixir 1.5 I just add &lt;code&gt;MyProject.Geolocation&lt;/code&gt;. I don’t even need to specify if that will start a worker or a supervisor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;# Many children here&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="no"&gt;MyProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Geolocation&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="ss"&gt;:one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;MyProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then in the Geolocation main entry module, I specify a child spec, which is a recipe to start a child under a supervisor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;MyProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Geolocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Cache&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;child_spec&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;start:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:start_link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Nice! Geolocation now controls which parts of the geolocation context is started under the main supervisor.&lt;/p&gt;

&lt;p&gt;If I later need to change it into a more complex scenario with a supervisor with multiple workers, I still only have to make changes to the context.&lt;/p&gt;

&lt;p&gt;Child specs can also define restart strategy and more. For reference see &lt;a href="https://hexdocs.pm/elixir/Supervisor.html#module-child-specification"&gt;the Supervisor docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did I gain?
&lt;/h2&gt;

&lt;p&gt;I implemented the geolocation functionality as a context, exposing only a single function (oh yes, and a child spec) to the outside world.&lt;/p&gt;

&lt;p&gt;Changing the inner works of the context is simple.&lt;/p&gt;

&lt;p&gt;Extracting the context as a standalone application or library is simple.&lt;/p&gt;

&lt;p&gt;Calling the functionality of the context is simple.&lt;/p&gt;

&lt;p&gt;Completely replacing the context with another context is simple.&lt;/p&gt;

&lt;p&gt;Changing the database structure of the db model is simple.&lt;/p&gt;

&lt;p&gt;I like simple.&lt;/p&gt;

&lt;p&gt;The complete feature was implemented in 329 lines split into 6 files. Only 10 percent, 32 lines, of that is revealed as public interface. Here is the complete main Geolocation module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Legolas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Geolocation&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Public interface for all geolocation related functionality
  """&lt;/span&gt;

  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Legolas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Geolocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Cache&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Legolas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Geolocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;CityLocation&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Legolas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Geolocation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;GoogleMaps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;

  &lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;geolocation&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;longitude&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;child_spec&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;%{&lt;/span&gt;
      &lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;start:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:start_link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Finds the geolocation for the given city address
  """&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;geolocation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;Cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;CityLocation&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;longitude&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And yes, I name the different repos in my project after LOTR characters.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this blog post ;)&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>patterns</category>
      <category>elixir</category>
    </item>
    <item>
      <title>Elixir PubSub Hub With Pattern Matching</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 18:58:50 +0000</pubDate>
      <link>https://dev.to/lasseebert/elixir-pubsub-hub-with-pattern-matching-38bj</link>
      <guid>https://dev.to/lasseebert/elixir-pubsub-hub-with-pattern-matching-38bj</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2017-04-15, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/lasseebert/subscribe-to-messages-with-pattern-matching-26b"&gt;previous post&lt;/a&gt;, I wrote about some ideas to utilize Elixir pattern matching when subscribing to messages in a pub-sub hub.&lt;/p&gt;

&lt;p&gt;The idea evolved to production code, and has now been extracted as an open source Elixir library called Hub.&lt;/p&gt;

&lt;p&gt;This post is about the making of the library.&lt;/p&gt;

&lt;p&gt;If you just want to see some code and example usage, look at the github page: &lt;a href="https://github.com/wise-home/hub"&gt;https://github.com/wise-home/hub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My use case: IoT messages
&lt;/h2&gt;

&lt;p&gt;As many ideas, this idea started when a need arose. I’m building an application that has persistent TCP connections to a lot of small linux boxes, which in turn each has a wireless connections to a lot of battery powered IoT devices.&lt;/p&gt;

&lt;p&gt;To get the terms right, the small linux boxes are called &lt;em&gt;gateways&lt;/em&gt; and the IoT devices are referred to as just &lt;em&gt;devices&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I have a two way communication with each device via the gateways. Most messages are measurements send on a regular basis from the devices, but the messages can also be administrative messages just to keep the network running or to configure devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flows
&lt;/h2&gt;

&lt;p&gt;Some messages come in flows. That is, the messages form a conversation and only make sense if the previous messages in the flow are known. As an example for this blog post, I’ll look at how I ask a gateway which authorized devices it knows about:&lt;/p&gt;

&lt;p&gt;I’ll send a &lt;em&gt;get entry request&lt;/em&gt; message to the gateway, asking for all known authorized devices starting from index zero.&lt;/p&gt;

&lt;p&gt;The gateway responds with a &lt;em&gt;get entry response&lt;/em&gt;, giving me all serial numbers of the devices that can fit in one message with some maximim message size. Let’s say that 10 device serials can fit in one message.&lt;/p&gt;

&lt;p&gt;I’ll re-query with another &lt;em&gt;get entry request&lt;/em&gt;, this time asking for devices starting at index 10.&lt;/p&gt;

&lt;p&gt;This continues until a get an empty &lt;em&gt;get entry response&lt;/em&gt;, which means that there are no more authorized devices. I can then perform some logic with the known authorized devices in my end of the application.&lt;/p&gt;

&lt;p&gt;This flow is easily recognized as a client-server pattern with a request and a response. However, the raw TCP connection I have does not know anything about server and client. In fact, the roles of the client and server might switch in the next flow.&lt;/p&gt;

&lt;p&gt;Until now, I have solved this in a not-so-nice way by almost ignoring that flows exists, and only care about single messages. In the above case, if I need all authorized devices, I’ll send a &lt;em&gt;get entry request&lt;/em&gt;. If I then later receive a &lt;em&gt;get entry response&lt;/em&gt;, I assume that it was a response to a previous request I send and I’ll “continue” the flow and send another get entry request.&lt;/p&gt;

&lt;p&gt;There are multuple problems with this approach:&lt;/p&gt;

&lt;p&gt;I cannot register that a timeout happened. If I send a request and do not receive a response within some time frame, I can not register this as being an error. I just fire-and-forget the request.&lt;/p&gt;

&lt;p&gt;I cannot handle complex flows where similar messages might mean something different depending on where we currently are in the flow or which flow it is received in.&lt;/p&gt;

&lt;p&gt;The network sends a lot of messages by itself, and I can not easily differentiate which messages was a response to something I send, and which messages I can ignore, because the network itself handles them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;A TCP connection to a gateway is handled by a &lt;code&gt;GenServer&lt;/code&gt;. Whenever a messages is received, it is until now handled within that same process.&lt;/p&gt;

&lt;p&gt;Now, I have changed this to use a pub-sub hub. Instead of handling the message in the same process, it publishes the message to a pub-sub hub. If no other processes subscribed to this exact message, it is processed by a default message handler, which mostly just logs the message.&lt;/p&gt;

&lt;p&gt;Whenever I want to start a flow of messages, I start a process that handles just that flow. The process is started as a &lt;code&gt;Task&lt;/code&gt; and is monitored by a &lt;code&gt;TaskSupervisor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The new process subscribes to a specific kind of message from a specific gateway and has a timeout. The process only exists in the lifespan of the flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hub, first version
&lt;/h2&gt;

&lt;p&gt;To make this possible, I needed to be able to subscribe to a particular message, perhaps with some particular value inside the message. The many different message types and combinations of values didn’t make this possible unless I want to publish each message to each process, which I think could quickly become a performance concern.&lt;/p&gt;

&lt;p&gt;Instead I would like to subscribe with an Elixir pattern, just like one can use them in guard clauses and function definitions.&lt;/p&gt;

&lt;p&gt;In my &lt;a href="https://dev.to/lasseebert/subscribe-to-messages-with-pattern-matching-26b"&gt;previous post&lt;/a&gt;, I described how I can save a pattern and use it later. I used this to build a first version if &lt;code&gt;Hub&lt;/code&gt;, which was powered by a &lt;code&gt;GenServer&lt;/code&gt; with the internal state being all subscriptions.&lt;/p&gt;

&lt;p&gt;In my flows, I can often limit a subscription to messages received via a specific gateway, so I use the gateway id as channel and can then subscribe with a pattern inside that channel.&lt;/p&gt;

&lt;p&gt;This worked but had some missing parts. I especially missed monitoring of processes, so that dead processes was auto-unsubscribed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hub, with Phoenix Presence
&lt;/h2&gt;

&lt;p&gt;Monitoring of processes is what Phoenix Presence is good at. I could easily change my GenServer to a simple module that used Phoenix Presence as the backend.&lt;br&gt;
My application was already using Phoenix and Presence, so I actually had one less running process by this change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hub, the standalone version
&lt;/h2&gt;

&lt;p&gt;I wanted to extract &lt;code&gt;Hub&lt;/code&gt; as a standalone hex package, but I did not want it to only being able to run inside a Phoenix application.&lt;/p&gt;

&lt;p&gt;I started to look at how Phoenix Presence is implemented and found out it is powered by Phoenix PubSub, which is a standalone package. Yay.&lt;/p&gt;

&lt;p&gt;I extracted Hub to its own repository and changed it to use Phoenix PubSub instead of Phoenix Presence. This required me to run two processes. A Tracker and a PubSub process. The documentation in Phoenix PubSub is good, so I was up and running in no time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Hub&lt;/code&gt; can now be used by anyone and has a simple interface.&lt;/p&gt;

&lt;p&gt;See more on the github page: &lt;a href="https://github.com/wise-home/hub"&gt;https://github.com/wise-home/hub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>pubsub</category>
    </item>
    <item>
      <title>Subscribe to messages with pattern matching</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 18:49:00 +0000</pubDate>
      <link>https://dev.to/lasseebert/subscribe-to-messages-with-pattern-matching-26b</link>
      <guid>https://dev.to/lasseebert/subscribe-to-messages-with-pattern-matching-26b</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2017-04-13, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Today I needed to build a small and simple publish/subscribe hub. The feature I cared about was to be able to subscribe to messages with Elixir pattern matching.&lt;/p&gt;

&lt;p&gt;Before I dive into that, let me explain the difference from a normal publish/subscribe hub.&lt;/p&gt;

&lt;p&gt;Often with the publish/subscribe pattern, subscribers subscribe to some topic and publishers publish a term to some topic.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Probably started by a supervisor:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;

&lt;span class="c1"&gt;# In our process&lt;/span&gt;
&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user_created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:user_created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# Do something with user&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# And in some other process:&lt;/span&gt;
&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user_created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is all fine. As long as we don’t need an infinite number of topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscribe with pattern matching
&lt;/h2&gt;

&lt;p&gt;In my application, I receive around 100 different types of messages from a lot of IoT devices. I would like different processes to be able to subscribe to incomming messages, but each process may have very different needs in terms of which messages they need to see.&lt;/p&gt;

&lt;p&gt;Some processes would like to see all messages originating from a specific device. Some would like all messages of a certain type. Some would like to subscribe to a message with a certain sequence number.&lt;/p&gt;

&lt;p&gt;This is not doable with the topic-approach. What I would really like is to use Elixir pattern matching to decide which messages to subscribe to.&lt;/p&gt;

&lt;p&gt;Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Subscribe to all messages from a specific origin&lt;/span&gt;
&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;origin:&lt;/span&gt; &lt;span class="s2"&gt;"1234"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Subscribe to all messages of a specific type&lt;/span&gt;
&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="no"&gt;SomeMessageType&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;

&lt;span class="c1"&gt;# Subscribe to all messages where the signal strength is bad&lt;/span&gt;
&lt;span class="no"&gt;PubSub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;signal_strength:&lt;/span&gt; &lt;span class="n"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;strength&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Can this be done in Elixir? YES! It can be done. Or at least in my small prototype, which I will start to use in a real application very soon to test it out.&lt;/p&gt;

&lt;p&gt;I started to have a look at &lt;code&gt;Kernel.match/2&lt;/code&gt; (docs here: &lt;a href="https://hexdocs.pm/elixir/Kernel.html#match?/2"&gt;https://hexdocs.pm/elixir/Kernel.html#match?/2&lt;/a&gt;), as it seemed to solve the same problem I was aiming at. Unfortunately, it couldn’t be used directly, but I found a lot of inspiration from the (pretty simple) source code of that macro.&lt;/p&gt;

&lt;p&gt;I began to play in &lt;code&gt;iex&lt;/code&gt; with &lt;code&gt;quote&lt;/code&gt;, &lt;code&gt;Macro.escape&lt;/code&gt; and other functions and macros that does something to the AST:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(41)&amp;gt; quote do: %{signal_strength: strength} when strength &amp;lt; 5
{:when, [],
 [{:%{}, [], [signal_strength: {:strength, [], Elixir}]},
  {:&amp;lt;, [context: Elixir, import: Kernel], [{:strength, [], Elixir}, 5]}]}
iex(42)&amp;gt; quote do
...(42)&amp;gt; case %{signal_strength: 7} do
...(42)&amp;gt; %{signal_strength: strength} when strength &amp;lt; 5 -&amp;gt; true
...(42)&amp;gt; _ -&amp;gt; false
...(42)&amp;gt; end
...(42)&amp;gt; end
{:case, [],
 [{:%{}, [], [signal_strength: 7]},
  [do: [{:-&amp;gt;, [],
     [[{:when, [],
        [{:%{}, [], [signal_strength: {:strength, [], Elixir}]},
         {:&amp;lt;, [context: Elixir, import: Kernel],
          [{:strength, [], Elixir}, 5]}]}], true]},
    {:-&amp;gt;, [], [[{:_, [], Elixir}], false]}]]]}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is almost all I need.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;I came up with this lovely function, which takes a quoted pattern and a value and returns &lt;code&gt;true&lt;/code&gt; if the value matches the pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;pattern_match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quoted_pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;ast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:case&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="no"&gt;Macro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;quoted_pattern&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="ss"&gt;:_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="no"&gt;Elixir&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;]}&lt;/span&gt;

  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eval_quoted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And it worked! This nice little function lets me use a saved pattern stored as AST to match a value.&lt;/p&gt;

&lt;p&gt;I assembled a simple Hub built on GenServer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Hub&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Publish/subscribe server.
  Subscription is done with a pattern.
  Example:
    {:ok, _pid} = Hub.start_link(name: :hub)
    Hub.subscribe(:hub, %{count: count} when count &amp;gt; 42)
    Hub.publish(:hub, %{count: 45, message: "You rock!"})
  """&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Starts the Hub GenServer process
  """&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Genserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;on_start&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Convenience macro for subscribing without the need to unquote the pattern.
  example:
    Hub.subscribe(:hub, %{count: count} when count &amp;gt; 42)
  """&lt;/span&gt;
  &lt;span class="k"&gt;defmacro&lt;/span&gt; &lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="kn"&gt;quote&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kn"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="no"&gt;Hub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe_quoted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kn"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kn"&gt;unquote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Macro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Subscribes the given pid to the quoted pattern
  example:
    Hub.subscribe(:hub, quote do: %{count: count} when count &amp;gt; 42)
  """&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;subscribe_quoted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;subscribe_quoted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoted_pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quoted_pattern&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Publishes the term to all subscribers that matches it
  """&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:publish&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;_from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;subscriber&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:publish&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;subscribers&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pattern_match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;pattern_match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;ast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:case&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="no"&gt;Macro&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:-&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="ss"&gt;:_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="no"&gt;Elixir&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;]}&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eval_quoted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice that it is possible to subscribe either using a function or a convenience macro.&lt;/p&gt;

&lt;p&gt;This lets me do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_pid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="ss"&gt;:hub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# In one process&lt;/span&gt;
&lt;span class="no"&gt;Hub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;signal_strength:&lt;/span&gt; &lt;span class="n"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;strength&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# In another process&lt;/span&gt;
&lt;span class="no"&gt;Hub&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:hub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;MyMessageType&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;signal_strength:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that’s it!&lt;/p&gt;

&lt;p&gt;If you know of a better or more obvious way to acheive the same thing, please let me know :)&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>pubsub</category>
    </item>
    <item>
      <title>Running observer inside a Vagrant box</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 18:40:09 +0000</pubDate>
      <link>https://dev.to/lasseebert/running-observer-inside-a-vagrant-box-4o87</link>
      <guid>https://dev.to/lasseebert/running-observer-inside-a-vagrant-box-4o87</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2016-11-28, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The :observer
&lt;/h2&gt;

&lt;p&gt;Elixir is shipped with a ton of nice features. One of those is the ability to start the erlang &lt;code&gt;:observer&lt;/code&gt; on a running appliciation and see the process tree, inspect indiviual processes and more.&lt;/p&gt;

&lt;p&gt;Just to recap, the observer is started from an iex session that is preloaded with the mix application we want to inspect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ iex -S mix
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)&amp;gt; :observer.start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that it is not necessary to start iex with &lt;code&gt;-S mix&lt;/code&gt; for observer to work.&lt;/p&gt;

&lt;p&gt;The observer is a GUI application that shows a lot of useful information about the running application. I use it a lot when developing if a Supervisor or GenServer is not behaving as I would expect.&lt;/p&gt;

&lt;p&gt;If you a new to observer, find a post that describes it in more detail, It is time well spent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vagrant
&lt;/h2&gt;

&lt;p&gt;I have a habit of running almost every software project inside a Vagrant virtual machine. Doing so allows me to have different versions of the database or other dependencies installed for each project.&lt;/p&gt;

&lt;p&gt;I also like that I don’t pollute my host machine with all kinds of software needed for a specific project.&lt;/p&gt;

&lt;p&gt;But running my development environment in Vagrant makes it harder to run the observer, since a Vagrant box is headless. I can’t run a GUI inside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to a node inside Vagrant
&lt;/h2&gt;

&lt;p&gt;Luckily Erlang has me covered. I can start a node outside my Vagrant (on my host machine) and connect to a running application inside Vagrant. To do so the two nodes must share a secret, known as a &lt;em&gt;cookie&lt;/em&gt; in Erlang terms.&lt;/p&gt;

&lt;p&gt;We also need to name each node, so that each of them can be found by name and host.&lt;/p&gt;

&lt;p&gt;Start the application inside Vagrant with a name and a cookie:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex --name my_app@192.168.33.10 --cookie 123 -S mix phoenix.server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;My project is a Phoenix project, which is why I start it with &lt;code&gt;mix phoenix.server&lt;/code&gt;. The IP address is the one of my Vagrant box as specified in my Vagrantfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.33.10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then I start a node on my host machine, and from that I can connect to the Vagrant node and start observer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex --name debug@127.0.0.1 --cookie 123
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(debug@127.0.0.1)1&amp;gt; Node.connect(:"my_app@192.168.33.10")
true
iex(debug@127.0.0.1)2&amp;gt; :obsever.start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the observer I can choose another node than the local one from the menu and I now see the application list and supervision trees from the remote node as if I had started observer from that node.&lt;/p&gt;

&lt;p&gt;Neat!&lt;/p&gt;

&lt;p&gt;But… I soon ran into trouble with a firewall.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to a node behind a firewall
&lt;/h2&gt;

&lt;p&gt;I later installed a firewall on my Vagrant box. Mostly to test the firewall setup on the production system. After this I could no longer connect from a remote iex. This was kind of expected since that is pretty much the firewall’s job: Only allow the specified ports to connect.&lt;/p&gt;

&lt;p&gt;So how do I configure a firewall to allow incoming node connections?&lt;/p&gt;

&lt;p&gt;It turns out that connecting to a remote node requires two ports to be open. The port for discovering the node and the port at which the actual connection is opened at.&lt;/p&gt;

&lt;p&gt;The discovery port defaults to 4369 but the other port is chosen at random in some huge range. We can limit this port range by specifying some erlang properties when starting iex.&lt;/p&gt;

&lt;p&gt;This limits the range to the single port &lt;code&gt;9000&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex --name my_app@192.168.33.10 \
    --cookie 123 \
    --erl '-kernel inet_dist_listen_min 9000' \
    --erl '-kernel inet_dist_listen_max 9000' \
    -S mix phoenix.server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now I can just allow port 4369 and 9000 in my firewall, and I’m good to connect to my firewalled application inside a Vagrant box!&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;I learned the erlang flags for limiting the port range by reading &lt;a href="http://blog.lucidsimple.com/2016/01/10/connecting-two-nodes-in-elixir.html"&gt;this good article&lt;/a&gt; about clustering by &lt;a href="https://twitter.com/lucidsimple"&gt;James Whiteman&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>vagrant</category>
    </item>
    <item>
      <title>Test driving a Phoenix endpoint, part I</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 18:27:13 +0000</pubDate>
      <link>https://dev.to/lasseebert/test-driving-a-phoenix-endpoint-part-i-5dg1</link>
      <guid>https://dev.to/lasseebert/test-driving-a-phoenix-endpoint-part-i-5dg1</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2016-10-18, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have worked part time professionally with Elixir for around a half year. Starting next month I will work with Elixir full time. And I can’t wait!&lt;/p&gt;

&lt;p&gt;The project I’m working on is split into four applications, one of which is a REST api using Phoenix as the main framework.&lt;/p&gt;

&lt;p&gt;I am very thrilled about Elixir, ExUnit, Ecto and a lot of other stuff in the Elixir ecosystem. But I have been a little careful not liking Phoenix too much.&lt;/p&gt;

&lt;p&gt;Maybe because I burned myself when I jumped into Rails around 5 years ago. Now I think Rails and Active* is everything Ruby should not be. I hope Phoenix will develop differently and it certainly looks good right now.&lt;/p&gt;

&lt;p&gt;But some of the example code attached to the Phoenix documentation is a bit alarming. I know. It is only example code and people shouldn’t copy-paste it into their own production code. But it could be exemplary examples.&lt;/p&gt;

&lt;p&gt;As an example, take a look at this update action from the Phoenix documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"user"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user_params&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;changeset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;changeset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changeset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;conn&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;put_flash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"User updated successfully."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="n"&gt;user_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;changeset&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"edit.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;changeset:&lt;/span&gt; &lt;span class="n"&gt;changeset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In my opinion, controllers should be doing web stuff and delegate all non-web stuff to other places in the codebase. Because the non-web stuff tend to grow in complexity and keeping it inside the controller is a mix of concerns.&lt;/p&gt;

&lt;p&gt;This example also shows the default behaviour of defining a changeset in the schema module. In the &lt;code&gt;User&lt;/code&gt; module in this case.&lt;/p&gt;

&lt;p&gt;Changesets should be defined in a specific context. Validations, accepted attributes and so on might change depending on which endpoint, cron-job or other code I’m in.&lt;/p&gt;

&lt;p&gt;Why? Because reusability, testability and maintainability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test driving
&lt;/h2&gt;

&lt;p&gt;This is the first part of a mini-series of blog posts. I estimate it will consist of 2–4 blog posts. This post is about testing the controller web logic and separating it from the non-web logic.&lt;/p&gt;

&lt;p&gt;Later posts will address other issues in testing such as writing a mock for an external service.&lt;/p&gt;

&lt;p&gt;Edit: Second post about mocks can be found &lt;a href="https://dev.to/lasseebert/mocks-in-elixir-19a4"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I will take you through the journey of test-driving a single Phoenix endpoint. The endpoint lives in &lt;code&gt;POST /users&lt;/code&gt; and is responsible for inviting a new user to our system.&lt;/p&gt;

&lt;p&gt;When we’re done, we have build an endpoint that will create an inactive user and send an email to the user with instructions on how to activate.&lt;/p&gt;

&lt;p&gt;When test-driving the code, it usually end up being reusable and maintainable, simply because we write the consumer of the code first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s get started!
&lt;/h2&gt;

&lt;p&gt;We will create a Phoenix application from scratch. We start by using the &lt;code&gt;phoenix.new&lt;/code&gt; mix task to create our application called &lt;code&gt;MyApp&lt;/code&gt;. Since we are building a REST api, we opt-out of using HTML and Brunch stuff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix phoenix.new --no-html --no-brunch my_app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  First test
&lt;/h2&gt;

&lt;p&gt;We start by building the create-user-part. Later we will build the send-activation-email-part.&lt;/p&gt;

&lt;p&gt;We can go one of two ways. Inside-out or outside-in. Start with the REST endpoint or start with the inner most layer of the application, which might be a database table or something else. Since we don’t know which layers come after the controller yet, we choose outside in: Starting in the controller and work our way in to the inner layers.&lt;/p&gt;

&lt;p&gt;The first thing we do before anything else, is writing a test. We will use the first test as a kind of integration test, testing all the layers of the application and the integration between them. Later we will add unit tests to test edge case behaviours of the controller and other pieces of code.&lt;/p&gt;

&lt;p&gt;Here is our first test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;UserController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;InviteTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;ConnCase&lt;/span&gt;

  &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"inviting a user responds with the new user"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;build_conn&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode!&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We will run this test. But not yet.&lt;/p&gt;

&lt;p&gt;First we should make some assumptions about what is going to fail. If we are wrong in our assumption, we have either written our test wrong or we have learned something new.&lt;/p&gt;

&lt;p&gt;Looking at the test, we first post some payload to &lt;code&gt;/users&lt;/code&gt; which should be ok. Then we assert that the response has status 201, which will not be true, because the endpoint does not exist yet. Let’s give it a try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
...

  1) test inviting a user responds with the new user (MyApp.UserController.InviteTest)
     test/controllers/user_controller/invite_test.exs:4
     ** (RuntimeError) expected response with status 201, got: 404, with body:
     {"errors":{"detail":"Page not found"}}
     stacktrace:
       (phoenix) lib/phoenix/test/conn_test.ex:362: Phoenix.ConnTest.response/2
       test/controllers/user_controller/invite_test.exs:9: (test)



Finished in 0.08 seconds
4 tests, 1 failure

Randomized with seed 448141
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Surely enough. Our tests reveals that we get a 404 when posting our payload. The test result almost tells us what to do next, which is one of the things I like about test driven development. The next thing we should do is to make sure our application understands a &lt;code&gt;POST /users&lt;/code&gt; which means we should add something to the router.&lt;/p&gt;

&lt;p&gt;We edit the &lt;code&gt;web/router.ex&lt;/code&gt; file:&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the route
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:router&lt;/span&gt;

  &lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="ss"&gt;:api&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:accepts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;pipe_through&lt;/span&gt; &lt;span class="ss"&gt;:api&lt;/span&gt;

    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="s2"&gt;"/users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;UserController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We added the &lt;code&gt;users&lt;/code&gt; resource and run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
Compiling 3 files (.ex)
...

  1) test inviting a user responds with the new user (MyApp.UserController.InviteTest)
     test/controllers/user_controller/invite_test.exs:4
     ** (UndefinedFunctionError) function MyApp.UserController.init/1 is undefined (module MyApp.UserController is not available)
     stacktrace:
       MyApp.UserController.init(:create)
       (my_app) web/router.ex:1: anonymous fn/1 in MyApp.Router.match_route/4
       (my_app) lib/phoenix/router.ex:261: MyApp.Router.dispatch/2
       (my_app) web/router.ex:1: MyApp.Router.do_call/2
       (my_app) lib/my_app/endpoint.ex:1: MyApp.Endpoint.phoenix_pipeline/1
       (my_app) lib/my_app/endpoint.ex:1: MyApp.Endpoint.call/2
       (phoenix) lib/phoenix/test/conn_test.ex:224: Phoenix.ConnTest.dispatch/5
       test/controllers/user_controller/invite_test.exs:7: (test)



Finished in 0.06 seconds
4 tests, 1 failure

Randomized with seed 999258
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The test tells us that we need the UserController, which was expected, since we reference it from the router, but did not yet create it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the controller
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;UserController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We just return status 201 and an empty JSON object.&lt;/p&gt;

&lt;p&gt;Again, we make assumptions about where the test will fail and run the test again. First, let’s review the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode!&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Take a moment to figure out where it will blow up next before we run the test. Done? Now for the test output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
Compiling 1 file (.ex)
Generated my_app app
...

  1) test inviting a user responds with the new user (MyApp.UserController.InviteTest)
     test/controllers/user_controller/invite_test.exs:4
     Assertion with == failed
     code: body["email"] == "alice@example.com"
     lhs:  nil
     rhs:  "alice@example.com"
     stacktrace:
       test/controllers/user_controller/invite_test.exs:12: (test)



Finished in 0.06 seconds
4 tests, 1 failure

Randomized with seed 773707
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ok, this was suprising! At least to me. My guess was that it would fail on &lt;code&gt;body["id"] &amp;gt; 0&lt;/code&gt; since we don’t return any id. But it fails on the email assertion on the next line. What happened?&lt;/p&gt;

&lt;p&gt;In Elixir everything is comparable to everything else. Not every comparison makes sense, but be sure to remember that we can compare any two data types.&lt;/p&gt;

&lt;p&gt;Looking in the Elixir documentation, we see this order for comparing non-same types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;number &amp;lt; atom &amp;lt; reference &amp;lt; function &amp;lt; port &amp;lt; pid &amp;lt; tuple &amp;lt; map &amp;lt; list &amp;lt; bitstring
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;nil&lt;/code&gt; is an atom and &lt;code&gt;0&lt;/code&gt; is a number, our assertion passes. Which means our test is wrong. Let’s fix it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode!&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;is_integer&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running the test again now shows that our expectations are correct (the expectation that the assertion is wrong) and we should return an id and an email to satisfy the test.&lt;/p&gt;

&lt;p&gt;But what should we return? We have no id and no user row in the database. We don’t even have a User schema. The next step is to actually create a user. The logic of user-creation is something we should delegate to another module, since we want to be able to reuse and unit test it.&lt;/p&gt;

&lt;p&gt;We update the controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;UserController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;conn&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This, of course, makes the test fail because &lt;code&gt;MyApp.Users.Invite&lt;/code&gt; does not exist yet. We will leave the controller test for now, while we create the invitation logic. After that we will return here and make it green.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the invitation logic
&lt;/h2&gt;

&lt;p&gt;Our efforts so far has lead us to the clarification that we need a &lt;code&gt;Users.Invite&lt;/code&gt; module which will contain the logic related to inviting a user.&lt;/p&gt;

&lt;p&gt;We start on a blank page since we’re building a new thing now. So just as before we will start by writing a failing test and take it from there. When this test is green, we will return to the controller test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;InviteTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;ModelCase&lt;/span&gt;

  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;

  &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"it creates a user"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;select:&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running the test tells us that we should create &lt;code&gt;MyApp.Users.Invite&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test test/contexts


  1) test it creates a user (MyApp.Users.InviteTest)
     test/contexts/users/invite_test.exs:6
     ** (UndefinedFunctionError) function MyApp.Users.Invite.call/1 is undefined (module MyApp.Users.Invite is not available)
     stacktrace:
       MyApp.Users.Invite.call(%{email: "alice@example.com"})
       test/contexts/users/invite_test.exs:7: (test)



Finished in 0.04 seconds
1 test, 1 failure

Randomized with seed 973477
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So we will create it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Repo&lt;/span&gt;

  &lt;span class="nv"&gt;@create_params&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;build_changeset&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create_user&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;build_changeset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Ecto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Changeset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;@create_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Ecto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Changeset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unique_constraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;create_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changeset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;changeset&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This code is pretty simple for now. It will 1) build a changeset using only the email and 2) save the changeset.&lt;/p&gt;

&lt;p&gt;Where does this fail when we run the test again? I have an assumption. Let’s see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test test/contexts
Compiling 1 file (.ex)

== Compilation error on file lib/my_app/contexts/users/invite.ex ==
** (CompileError) lib/my_app/contexts/users/invite.ex:17: MyApp.User.__struct__/1 is undefined, cannot expand struct MyApp.User
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Right. It fails because we don’t have a user schema yet. So we create the user schema and migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the schema and database table
&lt;/h2&gt;

&lt;p&gt;First we simply create the &lt;code&gt;User&lt;/code&gt; schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:model&lt;/span&gt;

  &lt;span class="n"&gt;schema&lt;/span&gt; &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;

    &lt;span class="n"&gt;timestamps&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice the lack of a &lt;code&gt;changeset&lt;/code&gt; function. When using the Phoenix generators, a &lt;code&gt;changeset&lt;/code&gt; function is created for us in the schema modules. We don’t need nor want this.&lt;/p&gt;

&lt;p&gt;We defined the changeset in the &lt;code&gt;Users.Invite&lt;/code&gt; module. This module contains all the logic we need to create and invite a user. Hence the changeset related to creating a user this way is also placed there. In other places we might need another changeset definition for creating a user.&lt;/p&gt;

&lt;p&gt;Defining the changeset where we use it allows us to maintain the changeset definition with confidence and without fear of breaking a random part of our application.&lt;/p&gt;

&lt;p&gt;We run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test test/contexts     


  1) test it creates a user (MyApp.Users.InviteTest)
     test/contexts/users/invite_test.exs:7
     ** (Postgrex.Error) ERROR (undefined_table): relation "users" does not exist
     stacktrace:
       (ecto) lib/ecto/adapters/sql.ex:463: Ecto.Adapters.SQL.struct/6
       (ecto) lib/ecto/repo/schema.ex:397: Ecto.Repo.Schema.apply/4
       (ecto) lib/ecto/repo/schema.ex:193: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
       test/contexts/users/invite_test.exs:8: (test)



Finished in 0.04 seconds
1 test, 1 failure

Randomized with seed 711320
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Just as we thought! We need a database table to fill the user into. We create a migration for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix ecto.gen.migration add_users_table
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Migrations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;AddUsersTable&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Ecto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;

      &lt;span class="n"&gt;timestamps&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix ecto.migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We migrate only for the &lt;code&gt;dev&lt;/code&gt; environment, since Phoenix by default is set up to migrate the test environment before every test run with these lines in the &lt;code&gt;mix.exs&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;aliases&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;aliases&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ecto.create --quiet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ecto.migrate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It’s time to run the test for &lt;code&gt;Users.Invite&lt;/code&gt; again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test test/contexts                           
.

Finished in 0.05 seconds
1 test, 0 failures

Randomized with seed 163288
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yay! First green test. We now have a reusable component in our application and it is working. This is a big deal.&lt;/p&gt;

&lt;p&gt;We can now revisit our failing controller test and make that green.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going back the the controller test
&lt;/h2&gt;

&lt;p&gt;Since we started with the test for &lt;code&gt;Users.Invite&lt;/code&gt; we only ran that test every time we tested. We now go back to run all tests again, since we only expect one test to fail.&lt;/p&gt;

&lt;p&gt;Let’s run all tests and see how the controller test fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test              
...

  1) test inviting a user responds with the new user (MyApp.UserController.InviteTest)
     test/controllers/user_controller/invite_test.exs:4
     ** (FunctionClauseError) no function clause matching in MyApp.Users.Invite.call/1
     stacktrace:
       (my_app) lib/my_app/contexts/users/invite.ex:8: MyApp.Users.Invite.call(%{"email" =&amp;gt; "alice@example.com"})
       (my_app) web/controllers/user_controller.ex:5: MyApp.UserController.create/2
       (my_app) web/controllers/user_controller.ex:1: MyApp.UserController.action/2
       (my_app) web/controllers/user_controller.ex:1: MyApp.UserController.phoenix_controller_pipeline/2
       (my_app) lib/my_app/endpoint.ex:1: MyApp.Endpoint.instrument/4
       (my_app) lib/phoenix/router.ex:261: MyApp.Router.dispatch/2
       (my_app) web/router.ex:1: MyApp.Router.do_call/2
       (my_app) lib/my_app/endpoint.ex:1: MyApp.Endpoint.phoenix_pipeline/1
       (my_app) lib/my_app/endpoint.ex:1: MyApp.Endpoint.call/2
       (phoenix) lib/phoenix/test/conn_test.ex:224: Phoenix.ConnTest.dispatch/5
       test/controllers/user_controller/invite_test.exs:7: (test)

.

Finished in 0.1 seconds
5 tests, 1 failure

Randomized with seed 633478
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ok? This was a surprise again. A function clause not matching in &lt;code&gt;Users.Invite&lt;/code&gt;. After reviewing the code we see that from the controller we pass in &lt;code&gt;%{"email" =&amp;gt; "someemail"}&lt;/code&gt; but &lt;code&gt;Users.Invite&lt;/code&gt; expects the email key to be an atom.&lt;/p&gt;

&lt;p&gt;The actual mistake was that we passed the params directly to the underlaying logic without first extracting the things we need. We will fix this now.&lt;/p&gt;

&lt;p&gt;We change&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;attrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will fix the problems. But note that normally we should parse the input params with an &lt;code&gt;Ecto.Schema&lt;/code&gt; or similar.&lt;/p&gt;

&lt;p&gt;When we only have one parameter this will be fine. If we’re dealing with just a few more parameters this method of manually parsing them will lead to bugs at some point. Parsing the params should be a job of it’s own, but for the sake of this blog post let’s keep it simple as above.&lt;/p&gt;

&lt;p&gt;We run the test again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
Compiling 1 file (.ex)
warning: variable user is unused
  web/controllers/user_controller.ex:6

....

  1) test inviting a user responds with the new user (MyApp.UserController.InviteTest)
     test/controllers/user_controller/invite_test.exs:4
     Expected truthy, got false
     code: body["id"] |&amp;gt; is_integer
     stacktrace:
       test/controllers/user_controller/invite_test.exs:11: (test)



Finished in 0.08 seconds
5 tests, 1 failure

Randomized with seed 847631
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yes! It now yells about the missing &lt;code&gt;id&lt;/code&gt; again, which was what we hoped would fail. This is because we still return an empty JSON object from the controller even though we create a user. We even get a warning that our &lt;code&gt;user&lt;/code&gt; is unused.&lt;/p&gt;

&lt;p&gt;Serializing an internal data type to a json object is also a job of it’s own, and many great libraries exists for this single purpose. Again, for the sake of the essence in this blog post, we simply just create a map and serialize it with Poison.&lt;/p&gt;

&lt;p&gt;This is the updated controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;UserController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;attrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
      &lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;

    &lt;span class="n"&gt;conn&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We run the tests again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
Compiling 1 file (.ex)
.....

Finished in 0.08 seconds
5 tests, 0 failures

Randomized with seed 174980
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally! For the first time since we started the blog post, all tests are green. We have now made a REST endpoint that can create a user. Good job!&lt;/p&gt;

&lt;h2&gt;
  
  
  Edge cases
&lt;/h2&gt;

&lt;p&gt;We have, however, only tested the “normal case” of the application. What should happen if we send an obviously incorrect email address like &lt;code&gt;"Alice and Bob"&lt;/code&gt;? What if we try to create a user with an email that exists on another user? What if the email is blank? Not submitted at all?&lt;/p&gt;

&lt;p&gt;A good REST API knows how to respond to all kinds of wierd input. A meaningful HTTP status code and a detailed error message can be a life-saver for an api user getting a response back from an invalid request.&lt;/p&gt;

&lt;p&gt;We will of course test drive edge cases just like we did with the “normal case”.&lt;/p&gt;

&lt;p&gt;We decide that we only want to handle one edge case for the sake of the blog post. In a real production site we should handle all the weird edge case scenarios we can think of.&lt;/p&gt;

&lt;p&gt;An invalid email should give &lt;code&gt;400: {"message": "email is invalid”}&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check for missing email
&lt;/h2&gt;

&lt;p&gt;Up until now we have gone through the testing very thoroughly. This process is usually pretty quick in practice, but very verbose in writing.&lt;/p&gt;

&lt;p&gt;We will now go up one level and dicuss which tests should be written and where certain parts of the logic belong. For this section, I will not post the entire test output for each test run.&lt;/p&gt;

&lt;p&gt;When checking for invalid email, the actual check should be in the &lt;code&gt;Users.Invite&lt;/code&gt; logic, since we also want to check for invalid emails if we reuse the module somewhere else. But the HTTP status and error message belongs in the controller, since that is both web specific and specific to that controller.&lt;/p&gt;

&lt;p&gt;We start by adding the test to the controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"invalid email gives a 400 response"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;build_conn&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="s2"&gt;"Alice and Bob"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode!&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"email is invalid"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This test fails because the code just creates the user with invalid email.&lt;/p&gt;

&lt;p&gt;We realize that the actual check should happen in &lt;code&gt;Users.Invite&lt;/code&gt; so we write a similar test for that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;  &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"it handles invalid email"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:invalid_email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="s2"&gt;"Alice and Bob"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice how much smaller this test is compared to the controller test. This is a sign that this is the right place to do edge case testing. If we want to test a lot of invalid and valid email addresses, we should add them to this test and just leave the single test in the controller.&lt;/p&gt;

&lt;p&gt;Running the test tells us that the logic in &lt;code&gt;Users.Invite&lt;/code&gt; accepts &lt;code&gt;"Alice and Bob"&lt;/code&gt; as a valid email. We fix this by ensuring that the email has at least one &lt;code&gt;@&lt;/code&gt;. This is intentionally simple, since we can’t possibly write a good validator for whatever RFC document describes what a valid email looks like.&lt;/p&gt;

&lt;p&gt;As an example &lt;code&gt;"Alice and Bob"@example.com&lt;/code&gt; is a valid email address. We just check for the @ because leaving it out is usually a sign that someone misread a form somewhere and entered a name instead of an email address. Our real email validation happens when we send out the activation email. If the user can get the email, the email is valid.&lt;/p&gt;

&lt;p&gt;We fix the logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;validate_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;email&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;build_changeset&lt;/span&gt;
      &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create_user&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;#...&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;validate_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sr"&gt;~r/@/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;
      &lt;span class="no"&gt;false&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:invalid_email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We wrap the user creation in a with &lt;code&gt;:ok &amp;lt;- validate_email(email)&lt;/code&gt;. This tells Elixir to go on if &lt;code&gt;validate_email&lt;/code&gt; returns &lt;code&gt;:ok&lt;/code&gt;, but return the result of that function call if it returns another value than &lt;code&gt;:ok&lt;/code&gt;. This makes it easy to step out early froma series of function calls.&lt;/p&gt;

&lt;p&gt;The new test now passes, but the controller test is still red. Let’s fix that. This is the entire controller after the fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;UserController&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:controller&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;attrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Invite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;render_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:invalid_email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;message:&lt;/span&gt; &lt;span class="s2"&gt;"email is invalid"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;render_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
      &lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Poison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;

    &lt;span class="n"&gt;conn&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;case&lt;/code&gt; statement. This is a place to add all the kinds of responses we can think of. When we later review the code, it’s easy to see what this controller can return.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summing up
&lt;/h2&gt;

&lt;p&gt;We have build a highly reusable and testable module for inviting a user. It is so reusable that it already has two consumers: The controller and the unit test.&lt;/p&gt;

&lt;p&gt;The controller we have build is only concerned with web-specific stuff like parsing params, returning the right HTTP status code and serializing the response body to JSON. It’s easy to read and easy to maintain.&lt;/p&gt;

&lt;p&gt;This blog post is long and it might seem like a long way to get to something very simple.&lt;/p&gt;

&lt;p&gt;But in practice, when you sit down and write code with your headphones on, listening to the best of Hans Zimmer, writing this code might take around 5 minutes. Maybe only 3 minutes on a good day.&lt;/p&gt;

&lt;p&gt;I don’t test because I’m afraid that the code base will break later on. I test because it yields a better code base. One that is easy to maintain and is highly reusable.&lt;/p&gt;

&lt;p&gt;That I can run my tests again and again to ensure that nothing is broken is just a nice bi-product.&lt;/p&gt;

&lt;p&gt;Stay tuned for Part II in which we’ll explore how to build a Mailer mock to use in tests.&lt;/p&gt;

&lt;p&gt;Edit: Part II is now ready &lt;a href="https://dev.to/lasseebert/mocks-in-elixir-19a4"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
      <category>testing</category>
    </item>
    <item>
      <title>Mocks in Elixir</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 18:26:48 +0000</pubDate>
      <link>https://dev.to/lasseebert/mocks-in-elixir-19a4</link>
      <guid>https://dev.to/lasseebert/mocks-in-elixir-19a4</guid>
      <description>&lt;h2&gt;
  
  
  Or “Test driving a Phoenix endpoint, part II”
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2016-10-32, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As the subtitle suggests, this is the second part of a blog post series about Phoenix and TDD. However, this post is not Phoenix-specific and the patterns presented here can be used in any Elixir application.&lt;/p&gt;

&lt;p&gt;The first part was about separation of concerns and how to make clean and reusable code within Phoenix. It can be found &lt;a href="https://dev.to/lasseebert/test-driving-a-phoenix-endpoint-part-i-5dg1"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This part is about testing modules that somehow makes external calls that we would like to avoid while testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking external calls
&lt;/h2&gt;

&lt;p&gt;Since I started with Elixir, I have wondered how to mock stuff in tests. And when to mock stuff.&lt;/p&gt;

&lt;p&gt;I come from Ruby, and I have developed a habit of injecting doubles for all dependencies of a class when unit testing the class.&lt;/p&gt;

&lt;p&gt;Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InviteUser&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;mailer: &lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user_repo: &lt;/span&gt;&lt;span class="no"&gt;UserRepo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@mailer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mailer&lt;/span&gt;
    &lt;span class="vi"&gt;@user_repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_repo&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:mailer&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:user_repo&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;mailer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_activation_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;RSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;InviteUser&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"#invite"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"sends an activation email"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;mailer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;instance_double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;create: &lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;user_repo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;instance_double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UserRepo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;send_activation_mail: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;invite_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;InviteUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;mailer: &lt;/span&gt;&lt;span class="n"&gt;mailer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user_repo: &lt;/span&gt;&lt;span class="n"&gt;user_repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;invite_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"me@example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mailer&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;have_received&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send_activation_mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is also possible in Elixir. One could just inject a module into a function, but it does not seem to be the preferred way in the Elixir community.&lt;/p&gt;

&lt;p&gt;I needed an answer to two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When do I use a mock?&lt;/li&gt;
&lt;li&gt;How do I mock?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There seems to be a very unambiguous trend in the community to the first question: Only use mocks when you would otherwise hit a third party service. The database does not count as a third party service here, since it is clearly possible to use it in tests.&lt;/p&gt;

&lt;p&gt;Since we’re building something that can send out emails (see Part I), we would surely like to somehow mock that out. That brings us to the second question: How do we mock?&lt;/p&gt;

&lt;h2&gt;
  
  
  Different mocking patterns
&lt;/h2&gt;

&lt;p&gt;I have explored the possibilities of mocking in Elixir and boiled it down to four different techniques, which I will briefly go through here.&lt;/p&gt;

&lt;p&gt;Spoiler: The last one is my preferred.&lt;/p&gt;

&lt;h3&gt;
  
  
  Injection with pure Elixir
&lt;/h3&gt;

&lt;p&gt;As explained with the Ruby example above, we could simply inject a module to a function and have a default value for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;InviteUser&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;invite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mailer&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_activation_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This would work and does not require any hex libs. But it does not feel very Elixirish. One of the things I love about Elixir is the stuff that happens at compile time. This runtime injection takes away that joy.&lt;/p&gt;

&lt;p&gt;I also like that everything is very clear in Elixir. You can look at a function and immediately know what it is doing. With runtime injection, anything can happen. We don’t know what kind of &lt;code&gt;mailer&lt;/code&gt; is send to the function.&lt;/p&gt;

&lt;p&gt;I like this method of mocking in Ruby, but I don’t like it for Elixir.&lt;/p&gt;

&lt;h3&gt;
  
  
  Injection with a library
&lt;/h3&gt;

&lt;p&gt;I have tried a hex package called &lt;code&gt;pact&lt;/code&gt; that offers dependency injection. It is basically the same as the injection with pure Elixir, except it uses a process to keep a store of modules and some nice convenience functions to create mocks of those modules from a test.&lt;/p&gt;

&lt;p&gt;But it is still runtime injection, which I don’t think is a good match in Elixir. An example with &lt;code&gt;pact&lt;/code&gt; would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;InviteUser&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;invite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Pact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"mailer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_activation_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And you would then be able to mock out the content of &lt;code&gt;MyApp.Pact.get("mailer")&lt;/code&gt; at runtime in tests.&lt;/p&gt;

&lt;p&gt;This seems like an even more poor solution than the injection with pure Elixir, since it requires a process to be running and more confusion when trying to read what a function actually does.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mocking with mock
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;mock&lt;/code&gt; is an Elixir library that uses the &lt;code&gt;meck&lt;/code&gt; Erlang library for mocking. I have not tried to use it, so what I’m saying here might be a little wrong. Please correct me.&lt;/p&gt;

&lt;p&gt;It seems that &lt;code&gt;mock&lt;/code&gt; does runtime substitution of module functionality with some dark magic meta programming. It reminds me a lot of the mocking functionality in RSpec from Ruby.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mock&lt;/code&gt; allows you to e.g. tell &lt;code&gt;String.reverse/1&lt;/code&gt; to accept a number and return the number times two(?). Here is an example from the readme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;efmodule&lt;/span&gt; &lt;span class="no"&gt;MyTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ExUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Case&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;async:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;

  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="no"&gt;Mock&lt;/span&gt;

  &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"multiple mocks"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;with_mocks&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;HashDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;[],&lt;/span&gt;
       &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;get:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(%{},&lt;/span&gt; &lt;span class="s2"&gt;"http://example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;html&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;[],&lt;/span&gt;
       &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;reverse:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;length:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;HashDict&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(%{},&lt;/span&gt; &lt;span class="s2"&gt;"http://example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;html&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;
      &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
      &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the kind of mocking that José Valim would describe as &lt;a href="http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/"&gt;“mock (verb), not mock (noun)”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If, for example, we would like to test an API client, we could mock (verb) the underlaying HTTP library to return the expected responses. In my humble opinion, this is just wrong and takes away all the functional part of Elixir.&lt;/p&gt;

&lt;p&gt;A better way, José says, is to create a mock (noun) and at compile time choose to use either the real implementation or the mock implementation.&lt;/p&gt;

&lt;p&gt;This leads us to the fourth and my preferred way to test external calls in Elixir.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compile time settings
&lt;/h3&gt;

&lt;p&gt;This section is basically a summary of &lt;a href="http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/"&gt;José’s post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We define two modules: One which holds the real implementation and one that holds the mock implementation. In the config we define that the test environment uses the mock implementation and all other environments use the real implementation.&lt;/p&gt;

&lt;p&gt;We then define a behaviour to make sure both implementations follow the same interface.&lt;/p&gt;

&lt;p&gt;That’s it. It’s simple, it’s compile time and it’s pure Elixir.&lt;/p&gt;

&lt;p&gt;Why is it good that it is happening at compile time, you might ask. It’s good because the compiled production code will be essentially the same as if we didn’t use a mock in tests.&lt;/p&gt;

&lt;p&gt;In the rest of this blog post we will create a mailer mock, TDD style.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the mailer
&lt;/h2&gt;

&lt;p&gt;Before we create a mock, we create a working mailer, which we test in the dev environment via iex. We write no tests for this implementation.&lt;/p&gt;

&lt;p&gt;I followed the Phoenix documentation of how to send emails and came up with this mailer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Mailgun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="ss"&gt;domain:&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:mailgun_domain&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;key:&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:mailgun_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nv"&gt;@from&lt;/span&gt; &lt;span class="s2"&gt;"support@myapp.com"&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_test_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;from:&lt;/span&gt; &lt;span class="nv"&gt;@from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;subject:&lt;/span&gt; &lt;span class="s2"&gt;"Test!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;text:&lt;/span&gt; &lt;span class="s2"&gt;"Test from MyApp"&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can easily one-time test this from iex -S mix and verify that we indeed get an email in our real mailbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test driving the mailer mock
&lt;/h2&gt;

&lt;p&gt;We are going to keep the mail composing functionaility in &lt;code&gt;MyApp.Mailer&lt;/code&gt; and move the Mailgun implementation to &lt;code&gt;MyApp.Mailer.Mailgun&lt;/code&gt;. Likewise we will create the mock in &lt;code&gt;MyApp.Mailer.Mock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But first, we write a test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MailerTest&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;ExUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Case&lt;/span&gt;

  &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"it uses mock in tests"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;
    &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_test_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"me@example.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mails&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mails&lt;/span&gt;

    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"me@example.com"&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Test from MyApp"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is mostly a test that the mock works as expected, but it also tests the small amount of mail composing functionality in the &lt;code&gt;send_test_mail&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;We run the test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
Compiling 16 files (.ex)

== Compilation error on file lib/my_app/mailer.ex ==
** (ArgumentError) application :my_app is not loaded, or the configuration parameter :mailgun_domain is not set
    (elixir) lib/application.ex:261: Application.fetch_env!/2
    lib/my_app/mailer.ex:3: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And we get a compilation warning? How? The mailer worked fine in development. We would expect the test to fail, since we don’t have a mock yet, not because it can’t compile.&lt;/p&gt;

&lt;p&gt;This is because the current &lt;code&gt;Mailer&lt;/code&gt; implementation uses Mailgun and fetches some settings from the config at compile time. We haven’t defined the mailgun settings for the test environment, which is why we get a compilation error.&lt;/p&gt;

&lt;p&gt;To fix this, we need to refactor the Mailer. Instead of having a Mailgun implementation, it should just delegate the mail sending part (not the mail composing part) to another module specified in the config.&lt;/p&gt;

&lt;p&gt;We should then write the Mailgun implementation and the Mock implementaion.&lt;/p&gt;

&lt;p&gt;First, let’s rewrite the Mailer, and save the Mailgun parts for later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@from&lt;/span&gt; &lt;span class="s2"&gt;"support@myapp.com"&lt;/span&gt;
  &lt;span class="nv"&gt;@mailer_impl&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:mailer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Behaviour&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nv"&gt;@callback&lt;/span&gt; &lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;key:&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_test_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;@mailer_impl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="ss"&gt;to:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;from:&lt;/span&gt; &lt;span class="nv"&gt;@from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;subject:&lt;/span&gt; &lt;span class="s2"&gt;"Test!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;text:&lt;/span&gt; &lt;span class="s2"&gt;"Test from MyApp"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We keep the composing logic and delegate the sending to a &lt;code&gt;@mailer_impl&lt;/code&gt; which we fetch from the config. We also define a behaviour which can be implemented by the different mailer implementations.&lt;/p&gt;

&lt;p&gt;Lets write the Mailgun and Mock implementations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailgun&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@behaviour&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Behaviour&lt;/span&gt;

  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Mailgun&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="ss"&gt;domain:&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:mailgun_domain&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="ss"&gt;key:&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_env!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:mailgun_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@behaviour&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Behaviour&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;mails&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;clear&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;_mails&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;mail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mail&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;into&lt;/span&gt;&lt;span class="p"&gt;(%{})&lt;/span&gt;
    &lt;span class="no"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;existing_mails&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;existing_mails&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="ss"&gt;:ok&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Each implementation just have to implement the &lt;code&gt;send_mail&lt;/code&gt; function as defined by the behaviour. The Mailgun mailer is mostly the same as our original Mailer.&lt;/p&gt;

&lt;p&gt;The Mock is implemented with an Agent to keep track of which emails are sent.&lt;/p&gt;

&lt;p&gt;Before running the tests again, we define the mailer implementation to use in the config.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;config/test.exs&lt;/code&gt; we add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mailer:&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And in &lt;code&gt;config/config.exs&lt;/code&gt; we add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;mailer:&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailgun&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This sets the Mailgun mailer as the default and overwrites the setting in tests.&lt;/p&gt;

&lt;p&gt;Time to run the test again to see it pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
Compiling 18 files (.ex)

== Compilation error on file lib/my_app/mailer/mailgun.ex ==
** (ArgumentError) application :my_app is not loaded, or the configuration parameter :mailgun_domain is not set
    (elixir) lib/application.ex:261: Application.fetch_env!/2
    lib/my_app/mailer/mailgun.ex:5: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What? We still get the same compilation error about missing mailgun settings!&lt;/p&gt;

&lt;p&gt;This is because even though we don’t use the Mailgun mailer in tests, it is still being compiled. We should just add some dummy settings in the test config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="ss"&gt;mailgun_domain:&lt;/span&gt; &lt;span class="s2"&gt;"notusedintests"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;mailgun_key:&lt;/span&gt; &lt;span class="s2"&gt;"notusedintests"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There! Lets run the tests again. Now it should be all green.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
.......

  1) test it uses mock in tests (MyApp.MailerTest)
     test/mailer_test.exs:4
     ** (exit) exited in: GenServer.call(MyApp.Mailer.Mock, {:update, #Function&amp;lt;0.6592501/1 in MyApp.Mailer.Mock.clear/0&amp;gt;}, 5000)
         ** (EXIT) no process
     stacktrace:
       (elixir) lib/gen_server.ex:596: GenServer.call/3
       test/mailer_test.exs:5: (test)



Finished in 0.1 seconds
8 tests, 1 failure

Randomized with seed 356689
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ok, now it compiles at least. Looking at the error message, we see that the Mock agent is not started. This is (doh) because we did not start it. We should add this to our &lt;code&gt;test_helper.exs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mailer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now it should be green!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix test
........

Finished in 0.09 seconds
8 tests, 0 failures

Randomized with seed 776617
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yay! All green. We have succesfully created a mock (noun) for our mailer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;It took me quite some time to figure out when and how to use mocks in Elixir. I think the approach described here is really nice and the most Elixirish of the patterns I have seen.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is simple&lt;/li&gt;
&lt;li&gt;It is pure Elixir. No libs needed.&lt;/li&gt;
&lt;li&gt;It is unobtrusive compared to the injection patterns&lt;/li&gt;
&lt;li&gt;It treats the mock as any other implementation, which allows for easy substitution of the real implementation.&lt;/li&gt;
&lt;li&gt;One could even have a one implementation for production, one for staging, one for dev and one for test.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope somebody saves some time by reading this blog post :)&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>testing</category>
      <category>mocking</category>
    </item>
    <item>
      <title>Iterating in Elixir</title>
      <dc:creator>Lasse Skindstad Ebert</dc:creator>
      <pubDate>Sun, 20 Oct 2019 06:36:08 +0000</pubDate>
      <link>https://dev.to/lasseebert/iterating-in-elixir-67e</link>
      <guid>https://dev.to/lasseebert/iterating-in-elixir-67e</guid>
      <description>&lt;p&gt;&lt;em&gt;This story was originally posted by me on Medium on 2016-10-07, but moved here since I'm closing my Medium account.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Like many Elixir developers I come from Ruby. Elixir is my first functional language after years of Java, VB.Net, C# and Ruby. And a little bit of Javascript.&lt;/p&gt;

&lt;p&gt;One of the first things that stroke me as being different in functional programming, was how I should map, reduce, loop and otherwise iterate data models.&lt;/p&gt;

&lt;h2&gt;
  
  
  The each
&lt;/h2&gt;

&lt;p&gt;In Ruby we might find something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;concat_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ok?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The issue of converting this to Elixir, is that everything is immutable in Elixir.&lt;/p&gt;

&lt;p&gt;Trying to do the same thing would yield an empty result, since everything that happens inside Enum.each stays inside Enum.each. It’s basically the Las Vegas of iterations. You only bring home the actions with side effects, like writing to the console or getting married.&lt;/p&gt;

&lt;p&gt;There are a number of ways to write the same code in Elixir. Let’s try with &lt;code&gt;Enum.filter&lt;/code&gt; and &lt;code&gt;Enum.reduce&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;concat_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;items&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ok?&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;&amp;amp;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This looks really nice! It exposes the intention of the code and makes it more readable.&lt;/p&gt;

&lt;p&gt;Couldn’t we do the same thing in Ruby? Yes, easily. The only problem is that a lot of the loop-like code with mutable state exists in Ruby code bases. Writing the Elixir code above in Ruby would give us this equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;concat_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;items&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:ok?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Be a good Ruby programmer. Don’t mutate state when you don’t need to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop
&lt;/h2&gt;

&lt;p&gt;In many programming languages it is possible to &lt;code&gt;loop&lt;/code&gt; and &lt;code&gt;break&lt;/code&gt; out of the loop. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_something&lt;/span&gt;
  &lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="kp"&gt;loop&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_external_http_call&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
      &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Service not available"&lt;/span&gt; 
      &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;body&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Trying to get an overview of this code takes a while :( It can break out of the loop two different places, and it mutates state between loop iterations.&lt;/p&gt;

&lt;p&gt;How could be better? Let’s force ourselves to immutability with Elixir and rewrite the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="p"&gt;\\&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;make_external_http_call&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_body&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fetch_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_something&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;tries&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="s2"&gt;"Service not available"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This was a big improvement in the Ruby code too! Of course, the lack of pattern matching and guard clauses makes it not-as-nice as the Elixir version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It might be hard at first to rewrite mutable, object-oriented iterations to an immutable functional language. For a long time it felt like I had to think backwards.&lt;/p&gt;

&lt;p&gt;But for some reason, immutability forces you to write easy-to-read and concise code, which is clearly a long-term benefit of any software project.&lt;/p&gt;

&lt;p&gt;I still write Ruby sometimes, and when I do, I tend to have a more functional code style than before I met Elixir. It helps me reason about my code and I avoid mixing logic and data. I have become a fan of the Ruby keyword &lt;code&gt;module_function&lt;/code&gt; which allows you to define a module with pure functions in it, much like in Elixir.&lt;/p&gt;

&lt;p&gt;Elixir and immutability is here to stay, and I see a big future for Elixir coming up.&lt;/p&gt;

</description>
      <category>elixir</category>
    </item>
  </channel>
</rss>
