[rspec-users] Could not find shared example group named "an admin is logged in"

Tim Gremore timgremore at gmail.com
Fri Oct 8 11:52:40 EDT 2010


Hi David - it's starting to sink in for me.  Your explanation was clear but
I have to ask if there is a better way when I hear that I'm using something
opposite its intended purpose :)

I've been able to send a block to my shared example group successfully -
working great so far!

Thanks again

On Fri, Oct 8, 2010 at 9:21 AM, David Chelimsky <dchelimsky at gmail.com>wrote:

>
> On Oct 8, 2010, at 8:20 AM, Tim Gremore wrote:
>
> On Thu, Oct 7, 2010 at 8:25 PM, David Chelimsky <dchelimsky at gmail.com>wrote:
>
>> On Oct 7, 2010, at 4:36 PM, Tim Gremore wrote:
>>
>> I'm stuck! Not sure what I'm missing but I'm struggling to get a shared
>> example group working with my controller specs.  Here is a piece of the
>> backtrace:
>>
>> /Users/20217633/.rvm/gems/ruby-1.9.2-p0 at rails3/gems/rspec-core-2.0.0.rc/lib/rspec/core/example_group.rb:68:in
>> `it_should_behave_like': Could not find shared example group named "an admin
>> is logged in" (RuntimeError)
>>  from
>> /Users/20217633/apps/curriculum/spec/controllers/users_controller_spec.rb:5:in
>> `block in <top (required)>'
>> from /Users/20217633/.rvm/gems/ruby-1.9.2-p0 at rails3/gems/rspec-core-2.0.0.rc/lib/rspec/core/example_group.rb:132:in
>> `module_eval'
>>  from /Users/20217633/.rvm/gems/ruby-1.9.2-p0 at rails3/gems/rspec-core-2.0.0.rc/lib/rspec/core/example_group.rb:132:in
>> `subclass'
>> from /Users/20217633/.rvm/gems/ruby-1.9.2-p0 at rails3/gems/rspec-core-2.0.0.rc/lib/rspec/core/example_group.rb:119:in
>> `describe'
>>  from /Users/20217633/.rvm/gems/ruby-1.9.2-p0 at rails3/gems/rspec-core-2.0.0.rc/lib/rspec/core/extensions/object.rb:7:in
>> `describe'
>> from
>> /Users/20217633/apps/curriculum/spec/controllers/users_controller_spec.rb:3:in
>> `<top (required)>'
>>
>> I'm using the following:
>>
>> rails 3.0
>> rspec-rails 2.0.0.rc (and friends)
>> cucumber-rails 0.3.2
>> factory_girl_rails 1.0
>>
>>
>> And the following for shared examples:
>>
>> module ExampleGroupMethods
>>
>>   describe "an admin is logged in", :shared => true do
>>     before(:each) do
>>       controller.stubs(:logged_in? => true)
>>       controller.stubs(:current_user => Factory.create(:admin))
>>     end
>>   end
>>
>>   describe "a supporter is logged in", :shared => true do
>>     before(:each) do
>>       controller.stubs(:logged_in? => true)
>>       controller.stubs(:current_user => Factory.create(:supporter))
>>     end
>>   end
>>
>>   describe "a manager is logged in", :shared => true do
>>     before(:each) do
>>       controller.stubs(:logged_in? => true)
>>       controller.stubs(:current_user => Factory.create(:manager))
>>     end
>>   end
>>
>> end
>>
>>
>> And the follow controller spec:
>>
>> describe UsersController do
>>
>>   it_should_behave_like "an admin is logged in"
>>
>>   describe "handling /users" do
>>
>>     before do
>>       @user = mock_model(User)
>>     end
>>
>>     def do_get
>>       get :index
>>     end
>>
>>     it "should assign users to the view" do
>>       User.should_receive(:all).with(:order => "last_name,
>> first_name").and_return([ @user ])
>>       do_get
>>     end
>>
>>   end
>>
>> end
>>
>>
>> And finally this spec_helper:
>>
>> # This file is copied to spec/ when you run 'rails generate rspec:install'
>> ENV["RAILS_ENV"] ||= 'test'
>> require File.expand_path("../../config/environment", __FILE__)
>> require 'rspec/rails'
>>
>> # Requires supporting ruby files with custom matchers and macros, etc,
>> # in spec/support/ and its subdirectories.
>> Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
>>
>> RSpec.configure do |config|
>>   # == Mock Framework
>>   #
>>   # If you prefer to use mocha, flexmock or RR, uncomment the appropriate
>> line:
>>   #
>>   # config.mock_with :mocha
>>   # config.mock_with :flexmock
>>   # config.mock_with :rr
>>   config.mock_with :rspec
>>
>>   # Remove this line if you're not using ActiveRecord or ActiveRecord
>> fixtures
>>   # config.fixture_path = "#{::Rails.root}/spec/fixtures"
>>
>>   # If you're not using ActiveRecord, or you'd prefer not to run each of
>> your
>>   # examples within a transaction, remove the following line or assign
>> false
>>    # instead of true.
>>   config.use_transactional_fixtures = true
>>
>>   # see http://asciicasts.com/episodes/157-rspec-matchers-macros
>>   config.include(ControllerMacros, :type => :controller)
>>
>>   # see http://pastie.org/870928
>>   config.include(ExampleGroupMethods, :type => :controller)
>> end
>>
>>
>> Anyone have a suggestion?  Thanks in advance
>>
>>
>> Shared examples have changed significantly in rspec-2. See
>> http://github.com/rspec/rspec-core/blob/master/features/example_groups/shared_example_group.feature to
>> get a feel for how they work now.
>>
>> The first thing is that :shared = true no longer works. You need to use
>> shared_examples_for. The other big change is that it_should_behave_like
>> creates a nested group, so if you do this:
>>
>> shared_examples_for "foo" do
>>   it "does something" do
>>   end
>> end
>>
>> describe "something" do
>>   it_behaves_like "foo" # it_behaves_like is an alias for
>> it_should_behave_like
>> end
>>
>> That's the same as doing this:
>>
>> describe "something" do
>>   context "behaves like foo" do
>>     it "does something" do
>>     end
>>   end
>> end
>>
>> This is a good thing, because it prevents the context of the shared group
>> from polluting the including group's scope, which can lead (and has led) to
>> a lot of confusion.
>>
>> Now in your case, you're using the shared group as a means of sharing
>> before blocks. While that works, it's the opposite of the intent of shared
>> groups, which is that the enclosing group should provide the context for the
>> shared group. What you _can_ do, however, to maintain the structure you
>> have, is to pass a block to it_should_behave_like, so your example change
>> from this:
>>
>> # rspec-1
>> describe UsersController do
>>   it_should_behave_like "an admin is logged in"
>>   describe "handling /users" do
>>     before do
>>       @user = mock_model(User)
>>     end
>>
>>     def do_get
>>       get :index
>>     end
>>
>>     it "should assign users to the view" do
>>       User.should_receive(:all).with(:order => "last_name,
>> first_name").and_return([ @user ])
>>       do_get
>>     end
>>   end
>> end
>>
>> to this:
>>
>> #rspec-2
>> describe UsersController do
>>   it_should_behave_like "an admin is logged in" do
>>     describe "handling /users" do
>>       before do
>>         @user = mock_model(User)
>>       end
>>
>>       def do_get
>>         get :index
>>       end
>>
>>       it "should assign users to the view" do
>>         User.should_receive(:all).with(:order => "last_name,
>> first_name").and_return([ @user ])
>>         do_get
>>       end
>>     end
>>   end
>> end
>>
>> HTH,
>> David
>>
>
> Thanks much Justin and David - very helpful.  David, you explained that I
>> could accomplish my goal by sending a block to it_should_behave_like, even
>> though that is not its intended purpose.  Is there a cleaner way to
>> accomplish my goal (spec'ing controller authentication and authorization)?
>
>
> Not sure if I was clear. I didn't mean to imply that passing a block a bad
> thing. Quite the contrary. Passing blocks is a big part of what makes shared
> groups in rspec-2 better than rspec-1 for their intended purpose:
>
>   to share examples for a conceptual (duck) type or a module, with the
> including group providing concrete context.
>
> What you're doing is the opposite - providing context using a shared
> group.
>
> Does that make sense? This is not to say that this is wrong, or evil. It's
> just the reverse of the intent.
>
> Take a close look at this scenario:
> http://github.com/rspec/rspec-core/blob/c5e6bc031404762edcda7789ecc04c6d340c8ef6/features/example_groups/shared_example_group.feature#L11.
> It demonstrates shared examples for a collection, applied to two different
> types, with the context provided by the "describe Array" group (which
> provides an instance of Array as the implicit subject) and the "describe
> Set" group (which provides a Set).
>
> Let me know if you have any questions.
>
> Cheers,
> David
>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>



-- 
Tim Gremore
920 471-1716
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20101008/25ae248f/attachment.html>


More information about the rspec-users mailing list