What's the best way to unit test protected & private methods in Ruby?

后端 未结 16 590
被撕碎了的回忆
被撕碎了的回忆 2020-12-12 10:47

What\'s the best way to unit test protected and private methods in Ruby, using the standard Ruby Test::Unit framework?

I\'m sure somebody will pipe up a

相关标签:
16条回答
  • 2020-12-12 11:11

    Here's one easy way if you use RSpec:

    before(:each) do
      MyClass.send(:public, *MyClass.protected_instance_methods)  
    end
    
    0 讨论(0)
  • 2020-12-12 11:12

    You can "reopen" the class and provide a new method that delegates to the private one:

    class Foo
      private
      def bar; puts "Oi! how did you reach me??"; end
    end
    # and then
    class Foo
      def ah_hah; bar; end
    end
    # then
    Foo.new.ah_hah
    
    0 讨论(0)
  • 2020-12-12 11:13

    In Test::Unit framework can write,

    MyClass.send(:public, :method_name)
    

    Here "method_name" is private method.

    & while calling this method can write,

    assert_equal expected, MyClass.instance.method_name(params)
    
    0 讨论(0)
  • 2020-12-12 11:17

    Instead of obj.send you can use a singleton method. It’s 3 more lines of code in your test class and requires no changes in the actual code to be tested.

    def obj.my_private_method_publicly (*args)
      my_private_method(*args)
    end
    

    In the test cases you then use my_private_method_publicly whenever you want to test my_private_method.

    http://mathandprogramming.blogspot.com/2010/01/ruby-testing-private-methods.html

    obj.send for private methods was replaced by send! in 1.9, but later send! was removed again. So obj.send works perfectly well.

    0 讨论(0)
  • 2020-12-12 11:19

    Just reopen the class in your test file, and redefine the method or methods as public. You don't have to redefine the guts of the method itself, just pass the symbol into the public call.

    If you original class is defined like this:

    class MyClass
    
      private
    
      def foo
        true
      end
    end
    

    In you test file, just do something like this:

    class MyClass
      public :foo
    
    end
    

    You can pass multiple symbols to public if you want to expose more private methods.

    public :foo, :bar
    
    0 讨论(0)
  • 2020-12-12 11:20

    I know I'm late to the party, but don't test private methods....I can't think of a reason to do this. A publicly accessible method is using that private method somewhere, test the public method and the variety of scenarios that would cause that private method to be used. Something goes in, something comes out. Testing private methods is a big no-no, and it makes it much harder to refactor your code later. They are private for a reason.

    0 讨论(0)
提交回复
热议问题