<?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: Nick Vernij</title>
    <description>The latest articles on DEV Community by Nick Vernij (@nickforall).</description>
    <link>https://dev.to/nickforall</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%2F9765%2F4987698.png</url>
      <title>DEV Community: Nick Vernij</title>
      <link>https://dev.to/nickforall</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nickforall"/>
    <language>en</language>
    <item>
      <title>Debugging and mocking third party services in Elixir with Mox</title>
      <dc:creator>Nick Vernij</dc:creator>
      <pubDate>Wed, 19 May 2021 15:12:42 +0000</pubDate>
      <link>https://dev.to/nickforall/debugging-and-mocking-third-party-services-in-elixir-with-mox-3gfb</link>
      <guid>https://dev.to/nickforall/debugging-and-mocking-third-party-services-in-elixir-with-mox-3gfb</guid>
      <description>&lt;p&gt;Almost every backend application uses them, third party services. Whether it's S3 for object storage, Segment for analytics or Firebase for push notifications. Those services are super helpful and do a lot of heavy-lifting, but in my experience usually do make debugging business logic on your local machine a pain, and testing them isn't easy either.&lt;/p&gt;

&lt;p&gt;There are some great solutions available in Elixir. In this post I'm sharing the approach I have been using for the past few years using Elixir. I'll be going over defining behaviours and using them for local debugging during development as well as writing tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining a behaviour
&lt;/h2&gt;

&lt;p&gt;Interfaces should be familiar for anyone coming from typed object-oriented languages such as Java or TypeScript. Elixir's equivalent of this is called a &lt;a href="https://hexdocs.pm/elixir/typespecs.html#behaviours"&gt;behaviour&lt;/a&gt;. By using type-specs we can define a module's functions in a behaviour, which can be implemented by multiple modules, usually called "callbacks" in Elixir.&lt;/p&gt;

&lt;p&gt;If you are unfamiliar with type-specs, I highly recommend &lt;a href="https://inquisitivedeveloper.com/lmw-elixir-69/"&gt;this comprehensive blog post&lt;/a&gt; by &lt;a href="https://inquisitivedeveloper.com"&gt;Kevin Peter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this post's example we want to define a simple behaviour that can send a push notification to a user. We're going to write a behaviour module that will describe the function definitions we need to send push notifications.&lt;/p&gt;

&lt;p&gt;In a behaviour, each &lt;code&gt;@callback&lt;/code&gt; annotation defines the type-spec of a function that is required on any implementation of this behaviour. For our push notifications use-case the simple behaviour below will do; a single &lt;code&gt;send_push&lt;/code&gt; function that takes a User struct as a recipient and a string as a title for the push notification.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushBehaviour&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# Sends a push notification to the given User with the given title.&lt;/span&gt;
  &lt;span class="c1"&gt;# Returns :ok if the message was sent or an :error tuple with an error message.&lt;/span&gt;
  &lt;span class="nv"&gt;@callback&lt;/span&gt; &lt;span class="n"&gt;send_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recipient&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;User&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;title&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="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="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="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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Stub, Debug and Production implementations
&lt;/h2&gt;

&lt;p&gt;Once we have determined what our behaviour looks like, we can start thinking about what our implementations may look like. I usually end up writing three implementations, one for each Mix environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development&lt;/strong&gt;: A behavior that helps us &lt;em&gt;debug&lt;/em&gt; our business logic locally without depending on secrets or even an internet connection. In the case of push notifications we can simply log the user's name and the message they will be receiving to the Elixir &lt;code&gt;Logger&lt;/code&gt;. For other use-cases, like object file storage, we can choose to write/modify/delete files on our local filesystem in a temporary folder instead of to for example Login.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt;: For testing you want to define a "&lt;em&gt;stub"&lt;/em&gt; that doesn't actually do anything with the data, and always acts as if anything you're trying to do is successful. You want to prevent calling your third party vendor hundreds of times while running tests. They may rate-limit you or it may incur costs. In those stubs you always want to return a succesful response, in our case that is &lt;code&gt;:ok&lt;/code&gt;, acting as if the push notification was sent succesfully. We'll go over testing error responses from your behaviour later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production&lt;/strong&gt;: This will call the third party service, which may be a library, rest API or whatever. Entirely up to you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementing a behaviour on a callback module is done by adding the &lt;code&gt;@behaviour&lt;/code&gt; decorator as well as implementing all of its defined callbacks. Here are some example implementations for our Stub, Debug and Production implementation.&lt;/p&gt;

&lt;p&gt;Our stub implementation will always return &lt;code&gt;:ok&lt;/code&gt;, it's there mainly to not raise any errors while running tests or compiling your app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;StubPush&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;"""
  Do nothing. Always succeed.
  """&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushBehaviour&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_push&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;_title&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;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;Our debug implementation will use &lt;code&gt;Logger&lt;/code&gt; to print the recipient's username and the title of the push notification. This is useful when writing your application locally and trying out your code without having to connect to your third party service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;DebugPush&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;"""
  Print a push notification to our logger
  """&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushBehaviour&lt;/span&gt;

  &lt;span class="kn"&gt;require&lt;/span&gt; &lt;span class="no"&gt;Logger&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_push&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;title&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;Logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sending a notification to user @&lt;/span&gt;&lt;span class="si"&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;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; with title &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&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;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a production example, I'm assuming we're using a fictional Firebase library for sending notifications. This can be any service or library for your use-case of course.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;FirebasePush&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;"""
  Send a push notification through firebase
  """&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushBehaviour&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;send_push&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;title&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;SomeFirebaseLibrary&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;some_send_function&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;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&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;h2&gt;
  
  
  Mocking
&lt;/h2&gt;

&lt;p&gt;The go-to library for working with mocks in Elixir is &lt;a href="https://github.com/dashbitco/mox"&gt;Mox&lt;/a&gt;, authored by José Valim. Follow the &lt;a href="https://github.com/dashbitco/mox#installation"&gt;instructions on their docs to have it installed&lt;/a&gt; so we can jump straight into setting up testing for our application's push notification.&lt;/p&gt;

&lt;p&gt;First we're going to head over to &lt;code&gt;test_helper.exs&lt;/code&gt; in your project. Every Elixir project with tests will have this file generated by default.&lt;/p&gt;

&lt;p&gt;We are going to add a mock with &lt;code&gt;Mox.defmock&lt;/code&gt;. This generates a module based on the behaviour we pass it. It's important to define a "stub" as well. Mox doesn't know what to return for each function and will error when a function is called without having an implementation. &lt;code&gt;Mox.stub_with&lt;/code&gt; will fill those functions with the always-succeeding callbacks we defined in our &lt;code&gt;StubPush&lt;/code&gt; module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# In test/test_helper.exs&lt;/span&gt;

&lt;span class="c1"&gt;# This will generate a module named MyApp.Infrastructure.MockPush&lt;/span&gt;
&lt;span class="no"&gt;Mox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defmock&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MockPush&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;for:&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;PushBehavior&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# This will define all callbacks&lt;/span&gt;
&lt;span class="no"&gt;Mox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stub_with&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MockPush&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;StubPush&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;ExUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now ready to start writing the tests for our push notification business logic. To prepare a test module for dealing with mox we need to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add &lt;code&gt;import Mox&lt;/code&gt; so we can use Mox's &lt;code&gt;expect&lt;/code&gt; functions later on&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;setup :verify_on_exit!&lt;/code&gt; which will perform some checks about your mocks after a test has run.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-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;PushTest&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;true&lt;/span&gt;

  &lt;span class="c1"&gt;# 1. Import Mox&lt;/span&gt;
  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="no"&gt;Mox&lt;/span&gt;
  &lt;span class="c1"&gt;# 2. setup fixtures&lt;/span&gt;
  &lt;span class="n"&gt;setup&lt;/span&gt; &lt;span class="ss"&gt;:verify_on_exit!&lt;/span&gt;

  &lt;span class="c1"&gt;# Here go your tests...&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 our tests we want to assert two main things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are our &lt;code&gt;send_push&lt;/code&gt; functions called with the right parameters&lt;/li&gt;
&lt;li&gt;Does our application handle errors returned from &lt;code&gt;send_push&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to do this we have to overwrite our stub behavior with a function specific to said test case. Mox provides the &lt;code&gt;expect&lt;/code&gt; function for this, which we imported earlier. &lt;code&gt;expect&lt;/code&gt; changes the function body for that specific test. Other tests will still use the stubbed behavior. Let's start with asserting whether the right parameters were given to &lt;code&gt;send_push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dashbit.co/blog/mocks-and-explicit-contracts"&gt;There's a cool blog-post by José Valim detailing the decisions that lead to the design of Mox. I'd recommend reading it if you want to dive a bit deeper.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When verifying parameters, you usually want to depend on pattern matching in Mox's case. With the pin operator (&lt;code&gt;^&lt;/code&gt;) we can verify whether &lt;code&gt;send_push&lt;/code&gt; was called with the same &lt;code&gt;user&lt;/code&gt; as we passed into &lt;code&gt;do_something_that_sends_push&lt;/code&gt;. Mox will ensure that your test fails when an &lt;code&gt;expect&lt;/code&gt; is never called or when there is no matching function clause.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;"Succesfully sends push notification to right user"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# Tip: ExMachina is a great library that helps generate entities like this.&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;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MockPush&lt;/span&gt;
  &lt;span class="c1"&gt;# Check if the user on `send_push` is the same user as we passed thru our call below&lt;/span&gt;
  &lt;span class="c1"&gt;# If the user does not match, this will throw a MatchError&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send_push&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;^&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;_title&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="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;do_something_that_sends_push&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also use &lt;code&gt;expect&lt;/code&gt; to return an error for &lt;code&gt;send_push&lt;/code&gt; and check whether our business logic handles this properly. Let's say we want our &lt;code&gt;do_something_that_sends_push&lt;/code&gt; function to propagate the push error to its caller, its test will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;"Succesfully propagates errors from push service"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# Tip: ExMachina is a great library that helps generate entities like this.&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;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MockPush&lt;/span&gt;
  &lt;span class="c1"&gt;# Check if the user on `send_push` is the same user as we passed thru our call below&lt;/span&gt;
  &lt;span class="c1"&gt;# If the user does not match, this will throw a MatchError&lt;/span&gt;
  &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send_push&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;_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_title&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="s2"&gt;"This user does not have push enabled"&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="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="n"&gt;do_something_that_sends_push&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="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="s2"&gt;"This user does not have push enabled"&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;h2&gt;
  
  
  Tying it all together
&lt;/h2&gt;

&lt;p&gt;These tests won't succeed yet. There is one last step before we can successfully try out our test and debug push implementations. We need to tell our application which implementation of our Push behavior it needs to call in certain environments. To do this we are going to use the &lt;code&gt;Application&lt;/code&gt; module which comes with Elixir, and the config files automatically generated in your Elixir project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# In config/dev.exs we use our push notification logger&lt;/span&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;:push_api&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;DebugPush&lt;/span&gt;

&lt;span class="c1"&gt;# In config/test.exs we use our Mock as named in Mox.defmock&lt;/span&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;:push_api&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;MockPush&lt;/span&gt;

&lt;span class="c1"&gt;# In config/prod.exs we want to use our Firebase client&lt;/span&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;:push_api&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;FirebasePush&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in any case where you need to send a push notification, you should get the currently configured push implementation from the Application's environment before you call it. You can wrap this in a module if you use the implementation a lot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# individually&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;get_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;:push_api&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_push&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="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# wrapped in a module&lt;/span&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;Infrastructure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Push&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;send_push&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;title&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;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_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;:push_api&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_push&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;title&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;You can now call &lt;code&gt;MyApp.Infrastructure.Push.send_push&lt;/code&gt;, which will look up the PushBehaviour implementation in your Application's environment and call the defined module. Try it out by running &lt;code&gt;iex -S mix&lt;/code&gt; and calling the function. For your dev environment it will log a message to the console!&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;Defining a behaviour and different implementations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are useful when debugging your app's business logic without having to depend on a third party service on your local machine&lt;/li&gt;
&lt;li&gt;Can be used to stub your calls to third party vendors, preventing you from calling them hundreds of times during tests.&lt;/li&gt;
&lt;li&gt;Can be used together with &lt;code&gt;Mox&lt;/code&gt; to assert whether your app behaves correctly with different responses from your third party vendors' APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, feel free to hit me up on &lt;a href="https://twitter.com/nickvernij"&gt;twitter&lt;/a&gt; if you have any questions or feedback.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>testing</category>
    </item>
    <item>
      <title>Testing your Elixir + Phoenix + Postgres app with Github CI</title>
      <dc:creator>Nick Vernij</dc:creator>
      <pubDate>Thu, 29 Aug 2019 15:38:43 +0000</pubDate>
      <link>https://dev.to/nickforall/testing-your-phoenix-elixir-app-with-github-ci-2gh1</link>
      <guid>https://dev.to/nickforall/testing-your-phoenix-elixir-app-with-github-ci-2gh1</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://nickvernij.nl/blog/github-ci-elixir.html?ref=dev.to"&gt;nickvernij.nl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub released their own CI recently, its UI and marketing look very fancy. I had to set up a new Elixir + Phoenix project and decided to give it a shot. &lt;/p&gt;

&lt;p&gt;It took me a full morning to get a green check, because the default elixir template is very minimal and the documentation for creating workflows is quite a lot of reading to get through.&lt;/p&gt;

&lt;p&gt;There are some nooks and crannies to get through, but when you get it to work it's very powerful. Essentially, the default Elixir workflow is fine for testing your average Elixir library, however a Phoenix app will need some additional setup and services. In my example I needed to set-up a PostgreSQL service.&lt;/p&gt;

&lt;p&gt;First of all we want to set the &lt;code&gt;MIX_ENV&lt;/code&gt; environment variable, so when we use ecto, it knows it should setup the test database. We can define global environment variables when defining the container in which our tests will run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;elixir:1.9.1-slim&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;MIX_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting up a database
&lt;/h2&gt;

&lt;p&gt;But to use ecto we actually need a database. In the workflow definition we can define a list of services. These are docker images that are prerequisites for our our test steps to run.&lt;/p&gt;

&lt;p&gt;This is what my services configuration looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
          &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let's go through this service definition rule-by-rule:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;image: postgres&lt;/code&gt; defines which docker image to pull in, in my case I am using the official docker image for Postgres: &lt;a href="https://hub.docker.com/_/postgres"&gt;https://hub.docker.com/_/postgres&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;5432:5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We always have to define which ports we want to expose for our docker container. In this case I am just exposing the default Postgres port&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The docker container we use has some environment variables defined, which it will use to configure the Postgres server. A full list of those variables can be found in the &lt;a href="https://hub.docker.com/_/postgres"&gt;Postgres Docker Hub description&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, we have to pass some additional options. These options will directly map to the &lt;code&gt;docker create&lt;/code&gt; command. The reason we need to add this health check is because &lt;code&gt;docker create&lt;/code&gt; exits before the container is actually ready to be used.&lt;/p&gt;

&lt;p&gt;Luckily for us, there is a simple command &lt;code&gt;pg_isready&lt;/code&gt; available, which we can check. As soon as the Postgres container is ready, your test run will continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting with the database
&lt;/h2&gt;

&lt;p&gt;The default Elixir workflow should already have some &lt;code&gt;steps&lt;/code&gt; defined. We are modifying the &lt;code&gt;Run Tests&lt;/code&gt; step a bit so it will create a database and pass some additional environment variables.&lt;/p&gt;

&lt;p&gt;All services defined will create a virtual host on the network, named after the service. This means you cannot simply reach the Postgres on localhost.&lt;/p&gt;

&lt;p&gt;I have added an environment variable in my run step that exposes the name of the services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Tests&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mix test&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;DB_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally I modified my Mix test configuration to read this variable and fall back on localhost by default&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Configure your database&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:myapp&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;Repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;username:&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;password:&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;database:&lt;/span&gt; &lt;span class="s2"&gt;"myapp_test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;hostname:&lt;/span&gt; &lt;span class="no"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"DB_HOST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="ss"&gt;pool:&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;Adapters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;SQL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Sandbox&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running your tests
&lt;/h2&gt;

&lt;p&gt;By default phoenix apps should have an alias for &lt;code&gt;mix run test&lt;/code&gt; that runs &lt;code&gt;ecto.setup&lt;/code&gt;, &lt;code&gt;ecto.migrate&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;When pushing new commits to your repository, the workflow should trigger, do all kinds of magic and run this command for you.&lt;/p&gt;

&lt;p&gt;You can find the full file in this gist: &lt;a href="https://gist.github.com/Nickforall/e49f5f3c37414e05f9a6c604accf2c3e"&gt;https://gist.github.com/Nickforall/e49f5f3c37414e05f9a6c604accf2c3e&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you have any questions feel free to hit me up on &lt;a href="https://twitter.com/nickforallnl"&gt;twitter&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://rocket-science.ru/hacking/2019/08/19/use-github-ci-for-elixir-projects?utm_campaign=elixir_radar_204&amp;amp;utm_medium=email&amp;amp;utm_source=RD+Station"&gt;Use Github CI for Elixir Projects&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idservices"&gt;https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idservices&lt;/a&gt; referenced August 29, 2019&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>github</category>
      <category>ci</category>
      <category>phoenix</category>
    </item>
    <item>
      <title>7 ways to write logic with Elixir's pattern matching</title>
      <dc:creator>Nick Vernij</dc:creator>
      <pubDate>Wed, 24 Apr 2019 09:17:06 +0000</pubDate>
      <link>https://dev.to/nickforall/7-ways-to-write-logic-with-elixir-s-pattern-matching-2bfk</link>
      <guid>https://dev.to/nickforall/7-ways-to-write-logic-with-elixir-s-pattern-matching-2bfk</guid>
      <description>&lt;p&gt;I have started using Elixir a little less than a year ago, looking back at this year I have learned a lot about functional programming and Elixir in particular. We currently use Elixir in production, as a graphQL back-end, and it works like a charm.&lt;/p&gt;

&lt;p&gt;The feature I love most is pattern matching, there are so many possibilities where I find ways to reduce the use of nested if-else blocks.&lt;/p&gt;

&lt;p&gt;To quickly explain pattern matching, here is a little example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# called with 1 apple&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;say_apples&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="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"You have 1 apple"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# called with any other amount that 1&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;say_apples&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&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="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"You have "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"apples"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By defining a literal as a function argument, we are matching against that literal. Meaning that when I call &lt;code&gt;say_apples&lt;/code&gt; with a first argument of &lt;code&gt;1&lt;/code&gt;, it will execute the method has a matching &lt;code&gt;1&lt;/code&gt; in its method definition. &lt;/p&gt;

&lt;p&gt;Using an identifier, as you normally would when writing methods, will match with anything. Be aware that matching happens in the order you function are written in. When your first method definition matches with everything, any methods below will never be called.&lt;/p&gt;

&lt;p&gt;So let's get to the point, here are 7 examples!&lt;/p&gt;

&lt;h2&gt;
  
  
  #1 "When" keyword
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# true when the number is lower than 10&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;lower_than_ten&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="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&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="no"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# false when the number is higher than 10&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;lower_than_ten&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;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;when&lt;/code&gt; keyword can be used to execute expressions when matching, for example comparing the given argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  #2 Matching struct types
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# prints the name of the type&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;print_type_name&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="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"user"&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;print_type_name&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="no"&gt;Post&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="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While I won't go into the details of Elixir's type system, you'll want to match whether a struct is a certain type at some point.&lt;/p&gt;

&lt;h2&gt;
  
  
  #3 Extracting variables from structs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# says hi to our user&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;say_hi&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="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&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;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hiya, "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&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;Structs are basically a key-value store, and sometimes you need one specific variable. I feel like in those cases, the above example reads way better than doing &lt;code&gt;user.name&lt;/code&gt; in the method body.&lt;/p&gt;

&lt;h2&gt;
  
  
  #4 Pattern match of variable
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# returns whether is_admin is true&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;can_administer&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="ss"&gt;is_admin:&lt;/span&gt; &lt;span class="no"&gt;true&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="no"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;can_administer&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="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can even pattern match on the value inside struct properties. Woah! Also notice how we use a &lt;code&gt;_&lt;/code&gt; if we don't really wanna use a variable but still want to match with everything.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I could just return &lt;code&gt;is_admin&lt;/code&gt;, I know, but this is an example :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  #5 String concatenation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# returns true if a string starts with "foo"&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;starts_with_foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&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="no"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;starts_with_foo&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="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can even use the concatenation operator in a method signature, to see if a string is prefixed with a certain string. &lt;/p&gt;

&lt;h2&gt;
  
  
  #6 First item in an array
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# returns the first item in an array&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&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="n"&gt;f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;first([1, 2, 3])&lt;/code&gt; will return &lt;code&gt;1&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  #7 Everything but the first item in an array
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# returns everything but the first item in an array&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;_&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="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;tail([1, 2, 3])&lt;/code&gt; will return &lt;code&gt;[2, 3]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The possibilities are endless! What are your favorite Elixir features?&lt;/p&gt;

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