Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stub unimplemented method in rspec

I'm testing my module and I decided to test it versus anonymous class:

  subject(:klass) { Class.new { include MyModule } }

MyModule uses method name inside klass. To let my specs work I need to stub this method name (which is unimplemented). So I wrote:

subject { klass.new }
allow(subject).to receive(:name).and_return('SOreadytohelp') }

but it raises:

 RSpec::Mocks::MockExpectationError: #<#<Class:0x007feb67a17750>:0x007feb67c7adf8> does not implement: name
from spec-support-3.3.0/lib/rspec/support.rb:86:in `block in <module:Support>'

how to stub this method without defining it?

like image 458
Filip Bartuzi Avatar asked Sep 02 '15 09:09

Filip Bartuzi


1 Answers

RSpec raises this exception because it is not useful to stub a method that does not exist on the original object.

Mocking methods is always error-prone because the mock might behave differently than the original implementation and therefore specs might be successful even if the original implementation would have returned an error (or does not even exist). Allowing to mock non-existing methods is just plain wrong.

Therefore I would argue that you should not try to bypass this exception. Just add a name method to your class that raises a clear exception if run outside of the test environment:

def self.name
  raise NoMethodError  # TODO: check specs...
end
like image 166
spickermann Avatar answered Oct 09 '22 00:10

spickermann