ExUnit test

1.- ExUnit

Es una librería de test que viene con Elixir y que nos proporciona todo lo necesario para cubrir nuestros test.

1.1.- Utilidades

  • Describe: Es una función muy utilizada para organizar y agrupar los test por funcionalidad.

      defmodule Factory.UserTest do
    
        describe "user" do
          test "expected values are validated" do
            user_changeset = User.changeset(%User{}, %{name: "John", email: "john@test.com"})
    
            assert user_changeset.valid?
          end
    
          test "email is required" do
            user_changeset = User.changeset(%User{}, %{name: "John", email: nil})
    
            refute user_changeset.valid?
          end
        end
      end
    
  • Setup: En algunos casos es necesario ejecutar algún tipo de código antes de lanzar nuestros test, para ello tenemos:

    • setup: es invocado antes de ejecutar a cada uno de los test.

        defmodule Factory.UserTest do
          setup do
            {:ok, name: "John"}
          end
          test "it works", %{name: name} do
           assert name == "John"
          end
        end
      
      • setup_all: es invocado una vez por módulo antes de ejecutar cada uno de los test.
          defmodule Factory.UserTest do
            setup_all do
              {:ok, name: "John"}
            end
            test "it works", %{name: name} do
              assert name == "John"
            end
          end
        
  • Mock: En algunos casos queremos comprobar ciertos comportamientos de otros servicios, como por ejemplo una llamada a una API, lo cual nos permite sobreescribir este servicio con la funcionalidad esperada.

    defmodule MyTest do
      use ExUnit.Case
      import Mock
    
      test "get" do
        with_mock HTTPotion,
            [get: fn("http://example.com", _headers) ->
                    HTTPotion.Response.new(status_code: 200,
                        body: "hello") end] do
          # Code which calls HTTPotion.get
          # Check that the call was made as we expected
          assert called HTTPotion.get("http://example.com", :_)
        end
      end
    end
    

## 2.- Ejemplos

Ejemplos de testing de los distintos tipos de módulos en Phoenix.

### 2.1.- Schema Module

defmodule Factory.Accounts.UserTest do use Factory.DataCase

alias Factory.Accounts.User

@valid_attrs %{email: "john@example.com", name: "John", bio: "my life ..."}
@invalid_attrs %{}

test "changeset with valid attributes" do
  changeset = User.changeset(%User{}, @valid_attrs)
  assert changeset.valid?
end

test "changeset with invalid attributes" do
  changeset = User.changeset(%User{}, @invalid_attrs)
  refute changeset.valid?
end

test "email is required" do
  changeset = User.changeset(%User{}, Map.delete(@valid_attrs, :email))
  refute changeset.valid?
end

end


### 2.2.- Controller

describe “index/2” do setup [:create_user] test “index/2 responds with all Users”, %{conn: conn, user: user} do

 response =
   conn
   |> get(user_path(conn, :index))
   |> json_response(200)

 expected = %{"data" => [%{"name" => user.name, "email" => user.email}]}

 assert response == expected

end end


### 2.3.- Channel

setup do {:ok, _, socket} = socket(“user_id”, %{some: :assign}) |> subscribe_and_join(RoomChannel, “room:lobby”)

{:ok, socket: socket}

end

test “ping replies with status ok”, %{socket: socket} do ref = push socket, “ping”, %{“hello” => “there”} assert_reply ref, :ok, %{“hello” => “there”} end