Test Me Some Elixir FizzBuzz

Time to check out Elixir's std for testing.

Bring it ExUnit!!

Since my FizzBuzz programs where using IO.puts I opted to try out ExUnit.CaptureIO instead of modifying them to returns strings.

Code.load_file("fizzbuzz.ex")

ExUnit.start

defmodule FizzBuzzTest do
  import ExUnit.CaptureIO

  use ExUnit.Case, async: true

  test "should print 'Fizz' for multiples of 3" do
    multiples_of_3 = fn ->
      FizzBuzz.start([3,9,99])
    end
    assert capture_io(multiples_of_3) == "Fizz\nFizz\nFizz\n"
  end

  test "should print 'Buzz' for multiples of 5" do
    multiples_of_5 = fn ->
      FizzBuzz.start([5,10,55])
    end
    assert capture_io(multiples_of_5) == "Buzz\nBuzz\nBuzz\n"
  end

  test "should print 'FizzBuzz' for multiples of 5 and 3" do
    multiples_of_3_and_5 = fn ->
      FizzBuzz.start([15,30,90])
    end
    assert capture_io(multiples_of_3_and_5) == "FizzBuzz\nFizzBuzz\nFizzBuzz\n"
  end

  test "should not print 'Buzz' for multiples of 3 AND 5" do
    multiple_of_3_and_5 = fn ->
      FizzBuzz.start([15])
    end
    assert capture_io(multiple_of_3_and_5) != "Buzz\n"
  end

  test "should not print 'Fizz' for multiples of 3 AND 5" do
    multiple_of_3_and_5 = fn ->
      FizzBuzz.start([15])
    end
    assert capture_io(multiple_of_3_and_5) != "Fizz\n"
  end

end

I really wanted to dry up the tests a bit move the multiples_of_* functions into a setup block, but I didn't see how. I'll have to look into that latter.

edit1:

Figured out the setup block to pass data to my tests and DRY'd up the test some.

Code.load_file("fizzbuzz.ex")

ExUnit.start

defmodule FizzBuzzTest do
  import ExUnit.CaptureIO

  use ExUnit.Case, async: true

  setup do
    {:ok,
      m_of_3: capture_io(fn -> FizzBuzz.start([3,9,99]) end),
      m_of_5: capture_io(fn -> FizzBuzz.start([5,10,55]) end),
      m_of_3_and_5: capture_io(fn -> FizzBuzz.start([15,30,90]) end)
    }
  end

  test "should print 'Fizz' for multiples of 3", context do
    assert context.m_of_3 == "Fizz\nFizz\nFizz\n"
  end

  test "should print 'Buzz' for multiples of 5", context do
    assert context.m_of_5 == "Buzz\nBuzz\nBuzz\n"
  end

  test "should print 'FizzBuzz' for multiples of 5 and 3", context do
    assert context.m_of_3_and_5 == "FizzBuzz\nFizzBuzz\nFizzBuzz\n"
  end

  test "should not print 'Buzz' for multiples of 3 AND 5", context do
    assert context.m_of_3_and_5 != "Buzz\nBuzz\nBuzz\n"
  end

  test "should not print 'Fizz' for multiples of 3 AND 5", context do
    assert context.m_of_3_and_5 != "Fizz\nFizz\nFizz\n"
  end

end