Forum: Ruby Testing private methods

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Peter H. (Guest)
on 2006-05-15 13:14
(Received via mailing list)
I have a class with a lot of private utility methods that makes the code
a lot cleaner. However I want to test them with unit tests. How can I do
this if they are private?
Robert F. (Guest)
on 2006-05-15 13:32
(Received via mailing list)
On 5/15/06, Peter H. <removed_email_address@domain.invalid> wrote:
> I have a class with a lot of private utility methods that makes the code
> a lot cleaner. However I want to test them with unit tests. How can I do
> this if they are private?
>
In your test code do:

class ClassUnderTest
  public :private_method1, :private_method2 # ...
end

as exemplified by:

feldt:~$ irb
irb(main):001:0> class T
irb(main):002:1> private
irb(main):003:1> def a; 1; end
irb(main):004:1> end
=> nil
irb(main):005:0> t = T.new
=> #<T:0xb7db90a8>
irb(main):006:0> t.a
NoMethodError: private method `a' called for #<T:0xb7db90a8>
        from (irb):6
        from :0
irb(main):007:0> class T
irb(main):008:1>  public :a
irb(main):009:1> end
=> T
irb(main):010:0> t.a
=> 1
irb(main):011:0>


/Robert F.
Daniel B. (Guest)
on 2006-05-15 13:32
(Received via mailing list)
Peter H. wrote:
> I have a class with a lot of private utility methods that makes the code
> a lot cleaner. However I want to test them with unit tests. How can I do
> this if they are private?
>
>
>

I believe the standard workaround is to use obj#send(:your_method).

Regards,

Dan
Peter H. (Guest)
on 2006-05-15 14:13
(Received via mailing list)
Thank you that looks to be just what I need.
Robert F. (Guest)
on 2006-05-15 14:55
(Received via mailing list)
On 5/15/06, Peter H. <removed_email_address@domain.invalid> wrote:
> Thank you that looks to be just what I need.
>
Since this is a bit "unsafe" (considering that some dev might use your
tests as a kind of API/code doc and might miss that they are private
or whatever) I tend to test my private methods in a separate TestCase
and/or name the test methods accordingly to make this "unsafeness"
clearer to the reader.

Example:

require 'test/unit'

class ClassUnderTest
  public :priv1, :priv2
end

class UnitTest_PrivateMethods_ClassUnderTest < Test::Unit::TestCase
  def test_01_private_priv1
  end

  # ...
end

class UnitTest_ClassUnderTest < Test::Unit::TestCase
  # "normal" tests goes here
end

Not sure if it really works but anyway...

I find the obj.send(:priv_method) technique a bit too cumbersome to
write if there are many tests.

Regards,

Robert
This topic is locked and can not be replied to.