Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mock_model("Transfer") creates persistent Class.new instead of loading ActiveRecord-backed class #28

Open
rdunlop opened this issue Mar 7, 2017 · 1 comment

Comments

@rdunlop
Copy link

rdunlop commented Mar 7, 2017

In a rails 4.2.7.1 app, with eager_load = false (and rspec-rails 3.4.2 (though I have the same behavior on 3.5.0))

In my suite, I have a spec which runs mock_model("Transfer")

This sometimes works correctly, and sometimes does not, depending on the order of my specs.

I have tracked it down to the fact that sometimes, before this is run, some other spec has referenced Transfer, thus loading the class definition.

Problem If the spec which does mock_model("Transfer") runs first, any subsequent reference to Transfer will return a Class.new, instead of the ActiveRecord-backed definition.

I think I've tracked this to https://github.com/rspec/rspec-activemodel-mocks/blob/master/lib/rspec/active_model/mocks/mocks.rb#L91

I feel I have 2 options:

  1. set eager_load = true in test.rb
  2. reference mock_model(Transfer) instead of mock_model("Transfer")

I am reporting this here not because I don't have a way forward, but because I think that this behavior doesn't follow with the documentation https://github.com/rspec/rspec-activemodel-mocks#mock "A String representing a Class that extends ActiveModel::Naming"

Am I using this gem incorrectly?

@rdunlop rdunlop changed the title mock_model("Transfer") doesn't clean up afterwards mock_model("Transfer") creates persistent Class.new instead of loading ActiveRecord model Mar 7, 2017
@rdunlop rdunlop changed the title mock_model("Transfer") creates persistent Class.new instead of loading ActiveRecord model mock_model("Transfer") creates persistent Class.new instead of loading ActiveRecord-backed class Mar 7, 2017
@TALlama
Copy link

TALlama commented May 22, 2018

We are seeing this same problem, which manifested for our team when we moved our continuous integration build into a cloud provider (seen on both Semaphore and CirceCI) that was splitting up our test suite. Sometimes, we'd get the following error:

NoMethodError: undefined method `_reflect_on_association' for SurveyAnswer:Class

I tracked that down to see that the only places that class was defined was where it should be, but that it was also used in a mock_model('SurveyAnswer') call. And sure enough, if I add a similar call to thebefore of the flickering spec, I can make it fail reliably. Using @rdunlop's link above, I then added the following line right after my new mock_model invocation:

p loc: SurveyAnswer.method(:primary_key).source_location

And the output shows that the SurveyAnswer constant is indeed being set to the mocked version:

{:loc=>["/Users/tal/.rvm/gems/ruby-2.3.4@recruit/gems/rspec-activemodel-mocks-1.0.3/lib/rspec/active_model/mocks/mocks.rb", 96]}

For now, we're doing eager_load=true on our CI provider, but it would be nice if this bug was fixed and we could avoid that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants