stub_const("::Name", with_this) does not work #200

coreyhaines opened this Issue Dec 2, 2012 · 16 comments


None yet
5 participants

coreyhaines commented Dec 2, 2012

Gives NameError
wrong constant name

Swapping to take out the :: seems to work. However, this was unexpected, since I'm referencing the constant that way.


alindeman commented Dec 2, 2012

Could we simply run .sub(/\A::/, "") over the first argument and get the correct behavior since the constant name must be fully-qualified?


myronmarston commented Dec 3, 2012

@alindeman -- yep, that's the exact fix I used :).

@coreyhaines -- it should work for you now. I did want to follow up on one of your tweets, though:

@myronmarston yeah, just using stub_const("Coderetreat", …) worked. Would prefer :: syntax, since I will have another Coderetreat class

Not sure if I'm misreading you or not (twitter-forced terseness makes misunderstanding easy) but your comment suggests you might be thinking that stub_const considers the constant scoping at the point of call (at least, that's the reason I prefix a const name with ::--to prevent it from considering the current constant scoping, since that's how normal constant lookup works). I wanted to clarify that it does not. The name must always be fully qualified. So even if your'e in a scope where a raw Coderetreat constant reference would resolve to a nested constant, stub_const("Coderetreat", blah) will look for a top-level constant called Coderetreat. We tried to document this well but we're certainly open for suggestions for how to document it better.


coreyhaines commented Dec 3, 2012

Thanks, guys,

I'll take a look at the constant scoping, as well. I'm hoping that it shouldn't matter.

I do rely on the scoping in my code to pick up the correct constant, but I don't think it should be a huge problem, as I rarely, if ever, use the same constant name from two different scopes in the same method. That seems like it would drive one insane. :)

If I notice anything else, I'll let you guys know.


I see this 'wrong constant' error message with these versions of RSpec:

$ gem list | grep rspec
guard-rspec (2.4.0)
rspec (2.12.0)
rspec-core (2.12.2)
rspec-expectations (2.12.1)
rspec-mocks (2.12.1)

$ gem outdated | grep rspec
$ bundle exec guard
# .. snip ..
  1) CarrierWave::Storage::ActiveRecord::StorageProvider#store!(file) with ::Rails sets the URL property on the returned file
     Failure/Error: stub_const('::Rails', 'Rails')
       wrong constant name 

myronmarston commented Jan 27, 2013

@richardkmichael -- what does this display?

$ bundle show rspec-mocks

I ask because depending on how you're using bundler, gems may be installed into a local cache -- so you could potentially be using rspec-mocks 2.12.0 (which had this bug) even though gem list indicates you have rspec-mocks 2.12.1 installed in your system gems.

Assuming that's not the issue, can you provide the full backtrace? Also, if there's anyway you can provide an executable example that triggers this error, that would be helpful, too.

$ bundle show rspec-mocks

Can I somehow ask RSpec to give me a full backtrace instead of stopping at my code? Or, I can probably insert Pry somewhere and do show-stack?


dchelimsky commented Jan 27, 2013

@richardkmichael if you type rspec help in a shell you'll see all of the command line options, including --backtrace, which gives you a full backtrace e.g. rspec --backtrace.

@dchelimsky Thank you. (Guard has the amusingly named wtf? method, though it is not helpful in this case.)

$ rspec --backtrace


  1) CarrierWave::Storage::ActiveRecord::StorageProvider#store!(file) with ::Rails sets the URL property on the returned file
     Failure/Error: stub_const('::Rails', 'Rails')
       wrong constant name 
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:47:in `const_defined?'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:47:in `const_defined_on?'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:314:in `block in mutate'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:313:in `each'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:313:in `inject'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:313:in `mutate'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:347:in `mutate'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:173:in `stub'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/example_methods.rb:91:in `stub_const'
     # ./spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb:58:in `block (2 levels) in <module:ActiveRecord>'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `instance_eval'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `block (2 levels) in let'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `fetch'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `block in let'
     # ./spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb:92:in `block (4 levels) in <module:ActiveRecord>'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:114:in `instance_eval'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:114:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:254:in `with_around_each_hooks'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:111:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:388:in `block in run_examples'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:384:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:384:in `run_examples'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:369:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/reporter.rb:34:in `report'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:25:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:80:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:17:in `block in autorun'

myronmarston commented Jan 27, 2013

Thanks! That backtrace suggests that this error is happening in the specs of that the case? If so, can you give us some repro steps? Would be nice to be able to clone your repo, checkout a particular branch, bundle install and run a particular spec file to trigger the error.

I was just about to add the comment that it's from this spec:

Except with stub_const("::Rails"), of course.

My apologies if it's horrible RSpec, I've perhaps done something I should not. :-)

I ran $ rspec --backtrace spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb.

I could work out a minimal case, of course.


alindeman commented Jan 27, 2013

Hmm, did you mean to stub the constant as a String? This effectively means Rails = "Rails"

Yes. It doesn't matter what it is, I handle the next, and only, message it receives afterward with stub_chain.


myronmarston commented Jan 27, 2013

I tried to repro the error in your project, but I can't bundle install:

The path `/Users/rmichael/Documents/Personal/Source/carrierwave` does not exist.

This is due to the hard-coded path in your Gemfile. Can you push a branch that corrects this? If you need a particular git revision, you can use the :ref option when declaring the gem in your Gemfile and give it a SHA.

Oops, sorry about that - I know it's broken for collaboration. I've been working alone and haven't cleaned it up for "release" yet, and forgot - despite asking about bundler config on their mailing list just today. :-/

I've pushed a repro branch with stub_const("::Rails"), working bundle install with a Gemfile.lock, here:

Then: rspec --backtrace spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb

myronmarston added a commit that referenced this issue Jan 28, 2013

Handle `stub_const("::SomeUndefinedConst")`.
I thought I fixed the problem in 17daf44,
but I missed this edge case.  That only fixed `stub_const("::SomeDefinedConst").

Fixes #200.

myronmarston commented Jan 28, 2013

@richardkmichael -- I just released rspec-mocks 2.12.2 with a fix for this issue (and a few other issues). If you upgrade, it should fix your issue. Thanks for reporting it!

@myronmarston Upgraded and fixed. No problem; thank you for fixing it so quickly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment