Rspec-core: `stub_const` on class changes it to a module

Created on 23 Feb 2016  路  2Comments  路  Source: rspec/rspec-core

I'm running into a strange issue with stub_const on a nested constant. I have a class, abbreviated here:

class Finder
  PAGE_SIZE = 50

  def initialize...
end

Everything works fine and as expected until in my feature specs I try to do:

stub_const('Finder::PAGE_SIZE', 2)
...do other stuff

Then I get the error:

NoMethodError:
  undefined method `new' for Finder:Module

It appears to be an autoloading issue, as if I simply add a reference to the class before I do the stubbing, it works as expected:

Finder
stub_const('Finder::PAGE_SIZE', 2)
...do other stuff

Most helpful comment

stub_const is part of rspec-mocks, not rspec-core so I'm going to close this here. You can re-open over there if needed (it helps us keep things organized if issues are opened against the correct repo).

That said, this sounds a lot like an issue users have run into before (rspec/rspec-mocks#201 and rspec/rspec-mocks#656) and RSpec is generally working as designed when users run into this kind of issue. If Finder does not exist and you want to stub Finder::PAGE_SIZE, RSpec generates a Finder module so it create the nested constant. Since Finder did not exist, RSpec has no way to know if should be a module or class, so it uses what we thought was the safest default (a module). If that's not what you want, you can load Finder before stubbing the constant (just use require!) or stub Finder first and then Finder::PAGE_SIZE.

All that said: your issue sounds slightly different (particularly the FormResponseFinder:Module bit given the constant is Finder -- huh?). If you want us to look into this more, please provide example code demonstrating the issue when you re-open over in rspec-mocks.

Also, if you have suggestions for improved documentation we can certainly do that as well.

All 2 comments

stub_const is part of rspec-mocks, not rspec-core so I'm going to close this here. You can re-open over there if needed (it helps us keep things organized if issues are opened against the correct repo).

That said, this sounds a lot like an issue users have run into before (rspec/rspec-mocks#201 and rspec/rspec-mocks#656) and RSpec is generally working as designed when users run into this kind of issue. If Finder does not exist and you want to stub Finder::PAGE_SIZE, RSpec generates a Finder module so it create the nested constant. Since Finder did not exist, RSpec has no way to know if should be a module or class, so it uses what we thought was the safest default (a module). If that's not what you want, you can load Finder before stubbing the constant (just use require!) or stub Finder first and then Finder::PAGE_SIZE.

All that said: your issue sounds slightly different (particularly the FormResponseFinder:Module bit given the constant is Finder -- huh?). If you want us to look into this more, please provide example code demonstrating the issue when you re-open over in rspec-mocks.

Also, if you have suggestions for improved documentation we can certainly do that as well.

Sorry, that was an incomplete edit. The class name is actually FormResponseFinder and I forgot to edit it down in one place. Will check out the issues on rspec-mocks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kevinlitchfield picture kevinlitchfield  路  6Comments

andyl picture andyl  路  6Comments

wwood picture wwood  路  5Comments

deepj picture deepj  路  3Comments

fimmtiu picture fimmtiu  路  3Comments