在Ruby中测试私有方法(rspec)

And*_*rey 48 ruby rspec

是的,我知道,测试私有方法并不是一个好主意(我读过这个帖子 - http://www.ruby-forum.com/topic/197346 - 以及其他一些方法)

但是我该如何测试以下代码?

我用的是xmpp4r.在我的公共方法中,#listen我开始接收jabber消息,如下所示:

def listen
  @client.add_message_callback do |m|
    do_things_with_message(m)
  end
end

private
def do_things_with_message(m)
  #
end
Run Code Online (Sandbox Code Playgroud)

#add_message_callback - 运行块,当消息到来时(在不同的线程中)

所以,测试#listen方法很难,而且测试xmpp4r比我的测试更多#do_things_with_message

如何做好并测试#do_things_with_message?:)(http://www.ruby-forum.com/topic/197346#859664)

将一个新对象的私有方法重构为一个公共的(和一个方法的类 - 它是无意义的)

编辑: 这是关于清洁代码和正确测试的理论问题.在我的第一个链接中,人们认为测试私有方法很差.我不想欺骗#send,但我也没有看到任何可行的重构方法

And*_*bbs 93

您可以使用send方法在ruby中调用私有方法.像这样的东西:

@my_object = MyObject.new
@my_object.send(:do_things_with_message, some_message)
Run Code Online (Sandbox Code Playgroud)

在一个看起来像这样的测试:

it "should do a thing" do
  my_object = MyObject.new
  my_object.send(:do_things_with_message, some_message)
  my_object.thing.should == true
end
Run Code Online (Sandbox Code Playgroud)

  • 我知道`#send`.关于清洁代码和正确测试的更多理论问题...... (6认同)

bur*_*mon 14

抛开你是否应该测试私有方法的问题,在Ruby中很可能暂时将私有方法公开.这就是我的意思:

# Metaprogrammatical magic to temporarily expose
# a Class' privates (methods).
class Class
  def publicize_methods
    saved_private_instance_methods = self.private_instance_methods
    self.class_eval { public *saved_private_instance_methods }
    yield
    self.class_eval { private *saved_private_instance_methods }
  end
end
Run Code Online (Sandbox Code Playgroud)

你会这样使用publicize_methods:

ClassToTest.publicize_methods do
  ...
  do_private_things_with_message(m).should ???
  ...
end
Run Code Online (Sandbox Code Playgroud)