defmodulePrinterTestdouseExUnit.Case test "print/1"do assert Printer.print(1)=="Number: 1" assert Printer.print("Hello")=="Text: Hello" assert Printer.print(%{name:"iago"})=="Map with name: iago"endend
Vamos rodar-lo:
mixtesttest/printer_test.exsCompiling1file (.ex)Generatedhello_worldappwarning:Printer.print/1isundefined (module Printerisnotavailableorisyettobedefined)Invalidcallfoundat3locations:test/printer_test.exs:5:PrinterTest."test print/1"/1test/printer_test.exs:6:PrinterTest."test print/1"/1test/printer_test.exs:7:PrinterTest."test print/1"/11) test print/1 (PrinterTest)test/printer_test.exs:4** (UndefinedFunctionError) functionPrinter.print/1 is undefined (modulePrinterisnotavailable)code:assertPrinter.print(1)=="Number: 1"stacktrace:Printer.print(1)test/printer_test.exs:5: (test)Finishedin0.02seconds (0.00s async,0.02ssync)1test,1failure
Recebemos relatório de erro por não possuir o módulo e função utilizados. Vamos cria-los. Para reoslver esse problema, poderiamos usar cond facilmente:
Vamos alterar nossa implementação, utilizando ainda o cond/2.
A leitura começou a ficar um pouco bagunçada, nao? Isso foi uma mudança pequena. Você pode me dizer que poderiamos usar uma função ali. E você estÔ certo em relação a isso. Mas ao invez disso, porque não isolamos a função print/1 para cada tipo de dado de entrar? Podemos fazer isso utilizando clauses. Elas são definidas ao lado da definição da função iniciando com a palavra chave when e uma operação a seguir. Vamos la:
Não preciso falar o quanto a leitura melhorou nesse exemplo certo? Temos diversas outras vantagens como, facilidade de extração e adição de novos tipos. Você pode perceber que as funções são controladas pelas funções seguidas do when. à ali que os guards moram.
defmodule Printer do
def print(arg) do
cond do
is_integer(arg) -> "Number: #{arg}"
is_bitstring(arg) -> "Text: #{arg}"
is_map(arg) -> "Map with name: #{arg.name}"
true -> "Noops"
end
end
end
defmodule PrinterTest do
use ExUnit.Case
test "print/1" do
assert Printer.print(2) == "Number 2 is even"
assert Printer.print(1) == "Number 1 is odd"
assert Printer.print("Hello") == "Text: Hello"
assert Printer.print(%{name: "iago"}) == "Map with name: iago"
end
end
lib/printer.ex
defmodule Printer do
require Integer
def print(arg) do
cond do
is_integer(arg) ->
if (Integer.is_even(arg) == true) do
"Number #{arg} is even"
else
"Number #{arg} is odd"
end
is_bitstring(arg)
-> "Text: #{arg}"
is_map(arg)
-> "Map with name: #{arg.name}"
true -> "Noops"
end
end
end
lib/printer.ex
defmodule Printer do
require Integer
def print(arg) when is_integer(arg) do
if (Integer.is_even(arg) == true) do
"Number #{arg} is even"
else
"Number #{arg} is odd"
end
end
def print(arg) when is_bitstring(arg), do: "Text: #{arg}"
def print(arg) when is_map(arg), do: "Map with name: #{arg.name}"
end
mix test test/printer_test.exs
Compiling 1 file (.ex)
.
Finished in 0.02 seconds (0.00s async, 0.02s sync)
1 test, 0 failures