Skip to content

Don't error out when config.mock_with or expect_with is re-specifying the current config #490

Closed
myronmarston opened this Issue Oct 31, 2011 · 10 comments

4 participants

@myronmarston
RSpec member

See this comment. config.mock_with :rspec was raising an error for a user due to the 2.7 change discussed here. In this case, raising the error was problematic for the user and unnecessary since it :rspec is the default and it was essentially a no-op.

We should change the code that raises an error so that it does nothing if these config options are simply re-specifying the current configuration (whether the default or not), since they are essentially a no-op in this case.

@nirvdrum

Looking forward to this fix. The other annoying thing is it went from a warning message about deprecated behavior being removed in RSpec 3.0 to something that just flat out errors in RSpec 2.7, breaking both with the contract of RSpec minor releases and the deprecation notice.

@myronmarston
RSpec member

The other annoying thing is it went from a warning message about deprecated behavior being removed in RSpec 3.0 to something that just flat out errors in RSpec 2.7, breaking both with the contract of RSpec minor releases and the deprecation notice.

The plan was to follow the deprecation/removal path until we got complaints about it. rspec/rspec-rails#371 contains a good portion of the discussion that went into changing the warning for all config-after-example-group-definition to an error for specific configs-after-example-group-definition. My comment there goes into detail about the specific ruby 1.9 bug we have been trying to work around with this.

For now, just remove config.mock_with :rspec as it doesn't actually do anything (that's the default that will get setup anyway).

Got any ideas for how we could have dealt with the ruby 1.9 bug better?

@nirvdrum

I actually mock with mocha, so removing the line isn't much of an option. I went through and changed all my require statements to be the relative require 'spec_helper', per the other thread, and that fixed it. The fix was very non-intuitive, as was the original error. I caught the error when upgrading from RSpec 1.3 => 2.6, so I didn't realize this was a recent change.

So, I can now run rake with RSpec 2.7 fine, but I've lost the ability to run any spec in isolation. I'm not wild about that prospect either.

I'm still running REE because 1.9.2 has been an unstable, buggy release for me. So unfortunately I can't weigh in more on that matter. Sounds like being stuck between a rock and a hard place. I guess having a wiki page or a better error message would have helped. For the life of me I couldn't figure out how I already had example groups defined. I didn't realize the configure stuff was non-reentrant. But if it can recall the example group state between calls, it should probably be able to remember its configuration between calls too, as you suggest above.

@myronmarston
RSpec member

The fix was very non-intuitive, as was the original error.

If you have any ideas for making it more intuitive, please feel free to update the wording of the error and submit a pull request :).

So, I can now run rake with RSpec 2.7 fine, but I've lost the ability to run any spec in isolation. I'm not wild about that prospect either.

I think you just need to re-order have you require and configure things. The important thing is that to prevent mysterious, confusing SystemStackError exceptions, RSpec must include the mock and expectation modules in RSpec::Core::ExampleGroup before users have defined any example groups...which means the configuration of those options must take place before an example group is defined. I would LOVE to not have this requirement, but this bug on ruby 1.9 makes it necessary. Here's on way you could re-arrange things to deal with this error:

spec/fast_spec_helper.rb:

require 'rspec'

RSpec.configure do |c|
  c.mock_with :mocha
end

spec/spec_helper.rb:

require 'fast_spec_helper'

# load rails or whatever to get your full app environment booted

RSpec.configure do |c|
  # other spec configuration
end

in a fast isolated spec:

require 'fast_spec_helper'

describe MyClass do
end

in a non-isolated spec:

require 'spec_helper'

describe MyRailsController do
end

The idea here is that we need to configure mock_with before any example groups are defined. spec_helper, in and of itself, doesn't make a spec slow and non-isolated; it's the fact that people's typical spec_helper loads tons of stuff and boots the whole rails environment. So, you can define another spec helper (fast_spec_helper) that gives you the minimum you need that MUST be configured before any example groups are defined, and require that both from isolated specs and also from spec_helper itself.

Let me know if that doesn't work for you.

And thanks for your patience on this manner! I know the changes here have caused pain for some users, and I really wish there was a better way...

@dchelimsky
RSpec member

Closed by #494

@dchelimsky dchelimsky closed this Nov 3, 2011
@dchelimsky dchelimsky added a commit that referenced this issue Nov 3, 2011
@dchelimsky dchelimsky changelog for #494 and #490 294e379
@kevinmccaughey

This appears to be broken again, I have had to remove "config.mock_with :rspec" to get it to work.

@myronmarston
RSpec member

@kevinmccaughey -- Sorry to hear that. Can you post a reproducible example? I'll take a look at it.

BTW, I posted a blog post describing the background to this issue:

http://myronmars.to/n/dev-blog/2011/11/recent-rspec-configuration-warnings-and-errors

...so if you want to understand more about what's going on, check that out.

@kevinmccaughey
@myronmarston
RSpec member

@kevinmccaughey -- can you post a link to the example in the rails tutorial?

@kevinmccaughey

I will link to the listing in the (free) online book (current version). The line is 2/3 of the way down: config.mock_with :rspec

http://ruby.railstutorial.org/chapters/static-pages#code:spork_spec_helper

Now this seemed sensible to me, so I was really confused when the only way to get the listing to work was to remove that line (config.mock_with :rspec)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.