Reputation: 23
I am new to RSpec and am diving into the deep end. I was hoping to test some trivial functions simply to get familiar with the RSpec DSL. So, to the point: How would I test the following snippit using RSpec's 3.1.7 syntax? More specifically, how do I test if a function is called?
manipulate_loc(loc, op, n)
x = loc.x.send(op, n)
y = loc.y.send(op, n)
yield x, y
end
def scale_up(loc, n)
manipulate_loc(loc, :*, n)
end
it 'can scale up Locations' do
expect(scale_up(subject,2)).to receive(:manipulate_loc).with(subject, 2)
end
I understand this is a weird example because I am passing blocks around, but what would ruby be without blocks!
Upvotes: 2
Views: 1896
Reputation: 198556
To test if a method is called, you mock the method (create a fake method) that will imitate the method whose calling you are testing. In Ruby, all functions are methods on something, even if that is the main object (self
in this context). If you are actually testing a method on some class (as you should; it is very bad for maintainability of Ruby code to define methods on main), replace self
with Foo.new
or similar.
It is hard to create a test case when you don't give us what the functions should do, and then write them incorrectly, so I'll fix them up a bit, and you can adapt them later to your use case:
def manipulate_loc(loc, op, n)
x = loc.x.send(op, n)
y = loc.y.send(op, n)
[x, y]
end
def scale_up(loc, n)
manipulate_loc(loc, :*, n)
end
it 'can scale up Locations' do
expect(self).to receive(:manipulate_loc).with(subject, :*, 2).and_return([4, 10])
expect(scale_up(subject, 2)).to equal([4, 10])
end
The expect... to receive... with... and_return...
is making a fake method that behaves in the specified way and replacing your method with it. Test passes if the fake method is called. (There is a further expectation that the method you are calling to call your mocked method is actually doing the right thing.)
Upvotes: 1