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

时间:2013-05-16 23:43:57

标签: 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

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

因此,测试#listen方法很困难,而且更多测试xmpp4r 比我的#do_things_with_message

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

重构一个新对象的私有方法 essentialy就像我让它们成为一个公共(和一个方法的类 - 它是无意义的

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

3 个答案:

答案 0 :(得分:89)

您可以使用the send method在ruby中调用私有方法。像这样:

@my_object = MyObject.new
@my_object.send(:do_things_with_message, some_message)

在一个看似类似的测试中:

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

答案 1 :(得分:13)

抛开 是否 测试私有方法的问题,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

您可以像这样使用publicize_methods

ClassToTest.publicize_methods do
  ...
  do_private_things_with_message(m).should ???
  ...
end

答案 2 :(得分:3)

您可能在所提到的所有资源中听到过这种想法,但正确的“理论”方法是测试@client收到add_message_callback,然后间接测试您的私有方法集成测试。单元测试的重点是你可以改变实现,你的测试仍然会通过