问题
I've been recruited as a SW Dev and I'm trying to get into Unit Testing with RSPEC and RR in ruby but having an hard time deciding on a specific strategy mainly because I was assigned to write unit tests to a code which is already written.
Consider the following code which is a part of a big method called method1:
if (["5234541252", "6236253223"].include?(self.id))
self.DoCheck
logs.add 'Doing check', "id = #{self.id}"
return
end
The relevant unit test for this part of the method would've been something like:
"should do check only if id = 5234541252 or 6236253223"
But i'm running into a few questions, basically involving best practices, for example:
How can I check if DoCheck has been called from within "method1" using RR and RSPEC?
I've tried using dont_allow(Object).DoCheck but it won't work.
describe :do_route do
it "should do check only if id = 5234541252 or 6236253223" do
user = Factory(:User)
user.id = "5234541252"
dont_allow(user).DoCheck
user.method1
end
Is there any other way to conclude if "DoCheck" was called or not?
回答1:
You can use 'Partial Mocking' technique on your object under tests. This means you need to set expectation that user.method1
sends DoCheck
message to the user
. RSpec can set this expectation with should_receive()
method. The test will fail if expectation won't be met.
Try the following code:
describe :do_route do
it "should do check if id = 5234541252 or 6236253223" do
user = Factory(:User)
user.id = "5234541252"
user.should_receive(:DoCheck) # set expectation that DoCheck will be called
user.method1 # execute
end
end
With RR this expectation may look like this:
describe :do_route do
it "should do check if id = 5234541252 or 6236253223" do
user = Factory(:User)
user.id = "5234541252"
mock(user).DoCheck # set expectation that DoCheck will be called
user.method1 # execute
end
end
Update
But be careful with usage of mock objects and partial mocks because they make your test code tightly coupled to the current behavior of the code under tests. If you are going to refactor this code in the future you will possibly get a lot of failing tests (those that use mocks). Try testing code without mocks (input-output) and use mocks only if they clearly explain intent of the class under test. When you write test with mock always ask yourself do you really need to assert that this method calls another method or what you really care is the output of the method or something else.
Hope this helps!
来源:https://stackoverflow.com/questions/8464376/ruby-unit-testing-techniques-mocking-and-stubbing