Class does not implement: method_name issue

22 views
Skip to first unread message

Abhinay Rao

unread,
Feb 8, 2021, 10:29:34 AMFeb 8
to rspec
I have updated rspec from 2.9 to 3.5. After the update test cases are failing where I stub the some method and expect presence on another method.

User.rb
class User
include Mongoid::Document
field :name, type: String

class << self
def test_method
rv = validate_something("test")
return rv if rv[:error]

user = User.new
user.name = "test#{rand(1..1000000)}"
user.save!
user.invoke_additional_tasks('test_method')

return { success: true, user: user }
end
end

def invoke_additional_tasks(test)
{ success: true }
end

private

class << self
def validate_something(params)
{ success: true }
end
end
end

user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
describe 'test_method' do
context 'when validate_something returns success' do
before(:each) do
allow(User).to receive(:validate_something).and_return(success: true)
end

it 'should invoke_additional_tasks on user' do
expect_any_instance_of(User).to receive(:invoke_additional_tasks).with('test_method')
User.test_method
end
end
end
end


I am getting the following error
Failure/Error: expect_any_instance_of(User).to receive(:invoke_additional_tasks).with('test_method')
       User does not implement: invoke_additional_tasks

Am I doing anything wrong here or it's a bug in rspec?

Phil Pirozhkov

unread,
Feb 8, 2021, 10:37:27 AMFeb 8
to Jack Royal-Gordon
I can't reproduce the failure with a slightly simplified version.

class User
attr_accessor :name

def invoke_additional_tasks(test)
{ success: true }
end

private

class << self
def validate_something(params)
{ success: true }
end
end
end

RSpec.describe User do
describe 'test_method' do
context 'when validate_something returns success' do
before(:each) do
allow(User).to receive(:validate_something).and_return(success: true)
end

it 'should invoke_additional_tasks on user' do
expect_any_instance_of(User).to
receive(:invoke_additional_tasks).with('test_method')

user = User.new
user.name = "test#{rand(1..1000000)}"
user.invoke_additional_tasks('test_method')
end
end
end
end

Abhinay Rao

unread,
Feb 9, 2021, 1:10:41 AMFeb 9
to rspec
That is because you are calling invoke_additional_tasks method on User instance. The test case in my example is for test_method which is a Class method. Please add Class method called test_method in User model to reproduce the issue.

user.rb
class User
attr_accessor :name

class << self
def test_method
rv = validate_something("test")
return rv if rv[:error]

user = User.new
user.name = "test#{rand(1..1000000)}"
user.save!
user.invoke_additional_tasks('test_method')

return { success: true, user: user }
end
end

def invoke_additional_tasks(test)
{ success: true }
end

private

class << self
def validate_something(params)
{ success: true }
end
end
end

user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
describe 'test_method' do
context 'when validate_something returns success' do
before(:each) do
allow(User).to receive(:validate_something).and_return(success: true)
end

it 'should invoke_additional_tasks on user' do
expect_any_instance_of(User).to receive(:invoke_additional_tasks).with('test_method')
User.test_method
end
end
end
end

Jon Rowe

unread,
Feb 9, 2021, 4:48:13 AMFeb 9
to rs...@googlegroups.com
Your original error comes from our verifying doubles feature, which you must have turned on as part of the upgrade process, you can turn it off if Mongoid isn't playing nicely with it with:

```
RSpec.configure do |config|
  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = false
  end
end
```

Both Phils, and yours, snippets pass in an empty Rails app, so its likely an interaction between Rails and other libraries you are using.

Cheers
Jon
Reply all
Reply to author
Forward
0 new messages