Reputation: 27563
I have a silly "queue-class[1]" with the following method, that I want to spec out with Rspec. I am not interested in testing if writing to the file-system works (It works, my computer works) but in whether or not the correct data gets written away.
def write transaction
File.open("messages/#{@next_id}", "w") {|f| f.puts transaction }
@next_id += 1
end
The spec for testing this is:
describe TransactionQueue do
context "#write" do
it "should write positive values" do
open_file = mock File
open_file.stub(:puts)
File.any_instance.stub(:open).and_yield(open_file)
File.any_instance.should_receive(:open)
open_file.should_receive(:puts).with("+100")
@queue = TransactionQueue.new
@queue.write("+100")
end
end
end
Running this, fails, because my Mocks never receive the expected "open" and "puts" messages.
Can I mock File
this way? Did I use the any_instance
correctly; is my attempt to stub a "block-yield" correct?
I'd rather not use extra gems like FakeFS when it can be avoided; this is not so much about getting it to work; bu mostly about actually understanding what is going on. Hence my attempt to avoid extra gems/layers of complexity.
[1] Class is from The Cucumber Book; but these tests have littel to do with Cucumber itself. I somehow broke the code when following the book; and want to find out what, by writing unit-tests for the parts that the book does not write tests for: the helper classes.
Upvotes: 3
Views: 1867
Reputation: 181785
It's not "any instance" of the File
class that you expect to receive the open
method; it's the File
class itself:
File.stub(:open).and_yield(open_file)
File.should_receive(:open)
Furthermore, don't use both a stub and an expectation. If you want to verify that File.open
is actually called:
File.should_receive(:open).and_yield(open_file)
If you merely want to stub the open
method in case it gets called, but don't want to require it as behaviour of the @queue.write
method:
File.stub(:open).and_yield(open_file)
(This is from memory, I haven't used RSpec for a few months.)
Upvotes: 6