在 Ruby 中测试私有方法 (rspec)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16599256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Testing private method in Ruby (rspec)
提问by Andrey
Yes, I know, that testing private methods it's not a good idea (and I read this thread - http://www.ruby-forum.com/topic/197346- and some others)
是的,我知道,测试私有方法不是一个好主意(我阅读了这个线程 - http://www.ruby-forum.com/topic/197346- 以及其他一些)
But how can I test the following code?
但是如何测试以下代码?
I use xmpp4r. In my public method #listenI start receive jabber
messages like so:
我使用 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- runs block, when message come (in different thread)
#add_message_callback- 运行块,当消息到来时(在不同的线程中)
So, testing #listenmethod it's difficult and it more testing xmpp4r
than my #do_things_with_message
所以,测试#listen方法很困难,而且比我的测试 xmpp4r 还要多#do_things_with_message
How to do all right and test #do_things_with_message?:)
(http://www.ruby-forum.com/topic/197346#859664)
如何做好并测试#do_things_with_message?:) ( http://www.ruby-forum.com/topic/197346#859664)
Refactor private methods to a new objectessentialy would be as I making them a public (and class with one method - it's senselessly
将私有方法重构为新对象本质上就像我将它们设为公共(和具有一个方法的类 - 这是毫无意义的
EDIT:This is more a theoretical question about clean code and the correct tests.
In my first link people argue that the test private methods poorly.
I don't want cheat with #send, but also I don't see any viable ways to refactor
编辑:这更像是一个关于干净代码和正确测试的理论问题。在我的第一个链接中,人们认为测试私有方法很差。我不想欺骗#send,但我也没有看到任何可行的重构方法
回答by Andrew Hubbs
You can call a private method in ruby using the sendmethod. Something like this:
您可以拨打使用红宝石私有方法的send方法。像这样的东西:
@my_object = MyObject.new
@my_object.send(:do_things_with_message, some_message)
In a test that would look something like:
在一个看起来像这样的测试中:
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
回答by buruzaemon
Putting aside the question of whether or not you shouldbe testing a private method, it is very possible in Ruby to temporarily make a private method public. Here is what I mean:
撇开是否应该测试私有方法的问题不谈,在 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
You would use publicize_methodslike this:
你会publicize_methods像这样使用:
ClassToTest.publicize_methods do
...
do_private_things_with_message(m).should ???
...
end
回答by enthrops
You probably heard this thought in all the resources that you mention, but the proper "theoretical" way to do it would be to test that @clientreceives add_message_callback, and then indirectly test your private methods with integration tests. The whole point of unit testing is that you can change implementation, and your tests will still pass
您可能在提到的所有资源中都听到过这种想法,但正确的“理论”方法是测试@client接收add_message_callback,然后使用集成测试间接测试您的私有方法。单元测试的全部意义在于您可以更改实现,并且您的测试仍然会通过

