It is stated in rspec doc that I should use double
method in order to create test double.
But I can see that it works perfectly ok even if I don't use double
. Is there anything wrong with not using double
? Also if I'm not using double how MyClass
gets stub
and other rspec methods? Are they available for all objects when running in rspec?
require 'spec_helper'
class MyClass
def self.run
new.execute
end
def execute
'foo'
end
end
describe MyClass do
it 'should stub instance method' do
obj = MyClass.new
obj.stub(:execute).and_return('bar')
obj.execute.should == 'bar'
end
it 'should stub class method' do
MyClass.stub(:run).and_return('baz')
MyClass.run.should == 'baz'
end
end
You now may verify doubles, which means "RSpec will check that the methods being stubbed are actually present on the underlying object if it is available", but "no checking will happen if the underlying object or class is not defined".
A partial test double is an extension of a real object in a system that is instrumented with. test-double like behaviour in the context of a test. This technique is very common in Ruby. because we often see class objects acting as global namespaces for methods.
Test doubles help you isolate the code under test so that you can test all facets of its behavior. In this example we've replaced three of the four collaborators with test doubles, deciding to scope the test to the behavior and collaboration of the code under test and one particular collaborator.
Mocks are “smart” stubs, their purpose is to verify that some method was called. They are created with some expectations (expected method calls) and can then be verified to ensure those methods were called.
Edit: I just reread your question and realized I didn't quite answer it. Leaving my original answer because it's related, but here's your specific answer:
The reason you don't need a double is because you're stubbing class methods, rather than instance methods. double
is only useful for dealing with instances of the class, not the class itself.
Old answer that explains double some more:
You should always use real classes instead of test doubles when you can. This will exercise more of your code and make your tests more comprehensive. Test doubles are used in situations where you can't or shouldn't use a real object. For example, if a class can't be instantiated without hitting an external resource (like a network or a database), or has a large number of dependencies, and you're just testing something that uses it, you might want to create a double and stub some methods on the double.
Here's a more specific example: let's say you are testing MyClass
, but in order to instantiate MyClass
, you need to pass in a FooLogger
:
mylogger = FooLogger.new
myclass = MyClass.new logger: mylogger
If FooLogger.new
opens a syslog socket and starts spamming it right away, every time you run your tests, you'll be logging. If you don't want to spam your logs during this test, you can instead create a double for FooLogger
and stub out a method on it:
mylogger = double(FooLogger)
mylogger.stub(:log)
myclass = MyClass.new logger: mylogger
Because most well-designed classes can be instantiated without any side-effects, you can usually just use the real object instead of a double, and stub methods on that instead. There are other scenarios where classes have many dependencies that make them difficult to instantiate, and doubles are a way to get past the cruft and test the thing you really care about.
In my experience, needing to use a double is a code smell, but we often have to use classes that we can't easily change (e.g. from a gem), so it's a tool you might need from time to time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With