Map são estruturas de dados no modelo chave valor (dicionário) que aceitam todos os tipos de dados. A definição dela segue o modelo %{} e os valores vão dentro das chaves.
Vamos criar uma estrutura simples:
test/maps_test.exs
defmodule MapsTest do
use ExUnit.Case
test "maps" do
data = %{
name: "iago"
}
# utilizando pattern matching
%{name: my_name_1} = data
assert my_name == "iago"
# Utilizando fech
{:ok, my_name_2 } = Map.fetch(data, :name)
assert my_name_2 == "iago"
# Utilizando acesso por indice
my_name_3 = data[:name]
assert my_name_3 == "iago"
# utilizando encadeamento
my_name4 = data.name
assert my_name4 == "iago"
# Quando acessado por indice, o que acontece quando o elemento não existe
my_name_5 = data[:not_exists_index]
assert my_name_5 == nil
# Quando acessado por encademamento, o que acontece quando o elemento não existe
assert_raise KeyError, fn ->
data = %{name: "iago"}
data.nonexistent_element
end
end
end
A função assert_raise/2 lida com expectativas de exceção do código, podendo fazer parte do teste para garantirmos o comportamento correto.
mix test test/maps_test.exs
warning: undefined field "not_exists_index" in expression:
# test/maps_test.exs:26
data.not_exists_index
expected one of the following fields: name
where "data" was given the type map() in:
# test/maps_test.exs:25
data = %{name: "iago"}
Conflict found at
test/maps_test.exs:26: MapsTest."test maps"/1
.
Finished in 0.03 seconds (0.00s async, 0.03s sync)
1 test, 0 failures
Existem diversas formas de lidar com Map, bastante entender como fica melhor para você.
defmodule MapsTest do
use ExUnit.Case
# ...
test "adding value in map" do
data = %{
name: "Iago"
}
new_data = %{data | name: "Elixir"}
assert data.name == "Iago"
assert new_data.name == "Elixir"
end
end
mix test
..
Finished in 0.05 seconds (0.00s async, 0.05s sync)
2 tests, 0 failures