Could not find shared example group named "an admin is logged in"

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@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@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@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@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@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

On Oct 7, 5:36 pm, Tim G. [email protected] wrote:

from /Users/20217633/.rvm/gems/ruby-1.9.2-p0@rails3/gems/rspec-core-2.0.0.rc/lib /rspec/core/example_group.rb:132:in

  controller.stubs(:current_user => Factory.create(:supporter))

end
@user = mock_model(User)
end
require ‘rspec/rails’

your

Anyone have a suggestion? Thanks in advance


rspec-users mailing list
[email protected]://rubyforge.org/mailman/listinfo/rspec-users

Hello,

You actually have to use the shared_examples_for method. So, your
code should look like this:

shared_examples_for “an admin is logged in” do
describe “an admin is logged in”, :shared => true do

On Oct 7, 2010, at 4:36 PM, Tim G. wrote:

I’m using the following:
describe “an admin is logged in”, :shared => true do
end

end

end

Requires supporting ruby files with custom matchers and macros, etc,

config.mock_with :rr

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

On Oct 8, 2010, at 8:20 AM, Tim G. wrote:

from /Users/20217633/.rvm/gems/ruby-1.9.2-p0@rails3/gems/rspec-core-2.0.0.rc/lib/rspec/core/extensions/object.rb:7:in `describe’

before(:each) do

end

  do_get

require File.expand_path(“…/…/config/environment”, FILE)

instead of true.

it_behaves_like “foo” # it_behaves_like is an alias for it_should_behave_like

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:
rspec-core/features/example_groups/shared_example_group.feature at c5e6bc031404762edcda7789ecc04c6d340c8ef6 · rspec/rspec-core · GitHub.
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

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 :slight_smile:

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

Thanks again

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)?