Testando métodos privados e protegidos no Ruby


Leia em menos de um minuto

Se você precisa testar métodos privados e/ou protegidos, faça isso de uma maneira elegante, sem se enrolar à toa.

Imagine que você tenha uma classe como esta:

class Emo
  private
    def deny
      "i'm not a emo! i'm from uk!"
    end

  protected
    def cut_wrists
      "oh god! nobody loves me! i'm gonna cut my wrists!"
    end
end
 

Para testar estes métodos, você pode usar o método send.

require "test/unit"

class TestEmo < Test::Unit::TestCase
  def setup
    @emo = Emo.new
  end

  def test_should_cut_wrists
    assert_equal @emo.send(:cut_wrists), "oh god! nobody loves me! i'm gonna cut my wrists!"
  end

  def test_should_deny_condition
    assert_equal @emo.send(:deny), "i'm not a emo! i'm from uk!"
  end
end

Uma dica rápida, mas que nem todos conhecem. Simples e muito, muito elegante!

Update: Ah, isso deixará de funcionar no 1.9 (você terá que usar o método send!), mas você pode corrigir isso quando ele for lançado, pois os testes que você escreve pegarão tal erro, certo? :)

Update 2: Quando o comportamento do send realmente mudar, acho que algo como isso irá resolver a situação (embora não tenha testado).

class Object
  def send(*args)
    send!(*args)
  end
end