"Undefined method" errors when running locally or in CI environment (Jenkins on Ubuntu) #174

damonatbrightroll opened this Issue Oct 16, 2012 · 25 comments


None yet

9 participants


I also filed this at thoughtbot/shoulda#224, but realized this may be a more appropriate location for it.

When running any of rspec, rake spec, bundle exec rspec, or bundle exec rake spec on my MacBook Pro, I see errors like this when running specs en masse:

$ rspec


  1) Activation associations 
     Failure/Error: it { should belong_to(:line_item) }
       undefined method `belong_to' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1:0x007fcf9e4b94f0>
     # ./spec/models/activation_spec.rb:7:in `block (3 levels) in <top (required)>'

  2) Activation validations 
     Failure/Error: it { should validate_presence_of(:line_item_id) }
       undefined method `validate_presence_of' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x007fcf9e5f0d00>
     # ./spec/models/activation_spec.rb:15:in `block (3 levels) in <top (required)>'

  3) Activation validations 
     Failure/Error: it { should validate_presence_of(:msg_id) }
       undefined method `validate_presence_of' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x007fcf9e5ee438>
     # ./spec/models/activation_spec.rb:17:in `block (3 levels) in <top (required)>'

  4) Activation validations 
     Failure/Error: it { should ensure_length_of(:msg_id).is_at_most(Activation::MAXIMUM_LENGTH_OF_MSG_ID) }
       undefined method `ensure_length_of' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x007fcf9e5f3b68>
     # ./spec/models/activation_spec.rb:18:in `block (3 levels) in <top (required)>'

etc. The errors seem only to occur against shoulda-style specs. However, I can run individual RSpec files without incident, e.g.,:

$ rspec spec/models/activation_spec.rb 

Top 10 slowest examples (0.03596 seconds, 94.2% of total time):
  Activation associations 
    0.01183 seconds ./spec/models/activation_spec.rb:7
  Activation validations 
    0.00784 seconds ./spec/models/activation_spec.rb:15
  Activation validations should be valid
    0.00515 seconds ./spec/models/activation_spec.rb:11
  Activation validations 
    0.00318 seconds ./spec/models/activation_spec.rb:18
  Activation validations 
    0.00314 seconds ./spec/models/activation_spec.rb:17
  Activation attributes 
    0.00215 seconds ./spec/models/activation_spec.rb:30
  Activation defaults status 
    0.00084 seconds ./spec/models/activation_spec.rb:24
  Activation attributes 
    0.0007 seconds ./spec/models/activation_spec.rb:30
  Activation attributes 
    0.00056 seconds ./spec/models/activation_spec.rb:30
  Activation attributes 
    0.00056 seconds ./spec/models/activation_spec.rb:30

Finished in 0.03919 seconds
14 examples, 0 failures

Here is my Gemfile:

source 'http://rubygems.org'
source 'http://gems.btrll.com'

gem 'rails', '3.2.8'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'brxutils'
gem 'mysql2'
gem 'state_machine'

# squeel grants additional ActiveRecord querying goodness without needing to embed SQL in code.
gem 'squeel'

# safe_attributes lets us overcome some legacy column names (e.g., 'errors') that collide with standard Rails-generated
# method names.
gem 'safe_attributes'

# strong_parameters gem should be used to prepare for Rails 4.0.
# See http://weblog.rubyonrails.org/2012/3/21/strong-parameters/
gem 'strong_parameters'

gem 'jquery-rails'
gem 'ar_query_builder', '1.0.1'

gem 'umsclient', '>= 0.4.1', :require => 'umsclient/frameworks/warden'

# used to integrate with other web services
gem 'rest_request', '2.10.1'

# used for role-based authorization
gem 'cancan'

# used for authentication
gem 'rails_warden'

# templating gem for json-based responses
gem 'rabl'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'ruby-debug19', :require => 'ruby-debug'

gem 'rq_request'
gem 'rq_client', '3.9.1'

gem 'redis'

# Used for stats collection with Graphite
gem 'statsd-ruby', '~> 0.4.0', github: 'jeremy/statsd-ruby', :require => 'statsd'

# needed for BrightRoll's build/deployment system
gem 'brpkg'

# solr support for full-text searching
gem 'sunspot_rails'

# used together with apache/nginx to serve rails applications
gem 'passenger', '3.0.13'

group :test do
  # factory_girl_rails makes it easy to create factories for unit tests.
  gem 'factory_girl_rails'

  # shoulda-matchers provides simpler syntax than vanilla RSpec in some cases.
  gem 'shoulda-matchers', '>= 1.4.0'

  # simplecov provides code coverage report in coverage/index.html.
  gem 'simplecov', :require => false

  # Allow to use/mock solr in tests
  gem 'sunspot-rails-tester'

group :development, :test do
  gem 'rspec-rails'

  # local solr server for development env
  gem 'sunspot_solr'

  # used by solr to show indexing progress
  gem 'progress_bar'

  # pretty-formats tables in console
  gem 'hirb'

More info:

$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.1.0]
$ rails --version
Rails 3.2.8

What's particularly troublesome is that I've got another project with basically the exact same Gemfile (the latter was used as a template for the former) and I've never seen this problem until now.

More information, after running with rspec -b:


  1) Activation associations 
     Failure/Error: it { should belong_to(:line_item) }
       undefined method `belong_to' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_1:0x007fc284896928>
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.11.3/lib/rspec/matchers/method_missing.rb:9:in `method_missing'
     # ./spec/models/activation_spec.rb:7:in `block (3 levels) in <top (required)>'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:113:in `instance_eval'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:113:in `block in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:253:in `with_around_each_hooks'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example.rb:110:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:378:in `block in run_examples'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:374:in `map'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:374:in `run_examples'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:360:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `block in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `map'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/example_group.rb:361:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `map'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:28:in `block in run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/reporter.rb:34:in `report'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:25:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:69:in `run'
     # /Users/damon/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `block in autorun'

I am also seeing this in our (Jenkins) CI environment.

thoughtbot, inc. member

Can you post your spec_helper as well? I can't see why this issue would occur so I'm hoping that can provide some insight.

require 'simplecov'
SimpleCov.start 'rails'

# 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'
require 'rspec/autorun'
require 'shoulda/matchers'
Dir[File.dirname(__FILE__) + "/spec_helpers/*.rb"].each {|file| require file }

# 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 }

DUMMY_ORG_ID = 12345
DUMMY_VALUE = 'some random string'

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

  config.include(ControllerMacros, :type => :controller)

  # 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

  # If true, the base class of anonymous controllers will be inferred
  # automatically. This will be the default behavior in future versions of
  # rspec-rails.
  config.infer_base_class_for_anonymous_controllers = false

  # FactoryGirl configuration:
  config.include FactoryGirl::Syntax::Methods

  # From https://makandracards.com/makandra/950-speed-up-rspec-by-deferring-garbage-collection
  config.before(:all) do
  config.after(:all) do

  # Sunspot configuration (mock session)
  $original_sunspot_session = Sunspot.session
  config.before do
    Sunspot.session = Sunspot::Rails::StubSessionProxy.new($original_sunspot_session)

  # Sunspot configuration: add ':solr => true' rspec metadata to allow example groups that use this metadata flag
  # to  use the original sunspot session
  config.before :each, :solr => true do
    Sunspot.session = $original_sunspot_session

  config.before(:suite) do
    # From http://robots.thoughtbot.com/post/21719164760/factorygirl-3-2-so-awesome-it-needs-to-be-released
    ActiveSupport::Notifications.subscribe('factory_girl.run_factory') do |name, start, finish, id, payload|
      execution_time_in_seconds = finish - start

      if execution_time_in_seconds >= 0.5
        $stderr.puts "Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}"

Here is an entire spec file as well, if that helps. Line numbers of failing tests have changed somewhat from what I pasted above, but the checks are the same.

require 'spec_helper'

describe Activation do
  let(:activation) { Activation.new(:line_item_id => 1, :msg_id => DUMMY_VALUE, :status => Activation::Status::PENDING) }

  describe 'associations' do
    it { should belong_to(:line_item) }

  describe 'validations' do
    it 'should be valid' do
      activation.should be_valid

    it { should validate_presence_of(:line_item_id) }

    it { should validate_presence_of(:msg_id) }
    it { should ensure_length_of(:msg_id).is_at_most(Activation::MAXIMUM_LENGTH_OF_MSG_ID) }

    it { should ensure_inclusion_of(:status).in_array(Activation::Status.values) }

  describe 'defaults' do
    subject { activation }

    its(:status) { should == Activation::Status::PENDING }

  describe 'attributes' do
    [:id, :line_item_id, :msg_id, :status, :errors_text, :warnings_text, :created_at,
     :updated_at].each do |expected_attribute|
      it { should respond_to(expected_attribute) }
thoughtbot, inc. member

@damonatbrightroll - can you send me an email : draper-at-thoughtbot-dot-com


We also get this issue on the Semaphore CI, have you been able to fix it? Thanks!


No luck as yet. @drapergeek had two suggestions for us:

  1. Remove simplecov.
  2. Disable "require 'shoulda/matchers'" from our spec_helper.rb.

The former had no effect. The latter immediately broke the build in environments that had otherwise been working. Continuing to investigate, but for now we are disabling all shoulda-related specs until we can resolve this.


@thibaudgg Can you please post your files as I did above so we can compare notes? If you can also paste the platform(s) on which you're building, that would be useful as well.


Removing the branch and re-adding it seems to have done the trick on Semaphore CI.

@damonatbrightroll We doesn't do anything special in our config, we just have gem 'shoulda-watcher in your Gemfile in test group.


@thibaudgg What do you mean by "removing the branch and re-adding it?" In git or something else?


@damonatbrightroll it's a feature of Semaphore CI, not in GIt.


I'm using Jenkins and I'm seeing this as well. @damonatbrightroll any word yet? @thibaudgg I wonder if there is an equivalent...measure one can take within Jenkins...(?)


@davidjoliver: No progress yet, unfortunately. Various shoulda tests remain commented out or replaced with (more verbose) vanilla RSpec for now, particularly should have_many, should have_one, should belong_to, should ensure_inclusion_of, should ensure_length_of, should accept_nested_attributes_for, should validate_presence_of, should validate_uniqueness_of, and possibly one or two others I'm forgetting offhand.


Just to clarify what @thibaudgg mentioned - removing the branch and re-adding it on Semaphore technically means that a repo (together with the cached bundle) is deleted and cloned again. So I think there's some randomness going on.

thoughtbot, inc. member

Unfortunately I have not been able to replicate this. If possible I would like to see someone create a bare bones project to replicate this issue. If a failure could be seem without using CI that would also be helpful even if we have to be specific about the OS and setup. Without being able to duplicate the issue my hands are somewhat tied at the moment.


I am on vacation this week but will take a stab at it next week.


I've tried but haven't been able to create a barebones project that demonstrates the bad behavior on my MBP. Anyone else able to do so?


I just ran into this issue yesterday, so I was determined to figure out what was going on. I'm not sure if the root cause of your problem is the same as mine, but I was able to create a bare bones project that replicates the issue: https://github.com/cade/shoulda-matchers-goes-boom

Instructions are in the README for how to reproduce and artificially 'fix' the problem. Hope this helps.


+1 for any progress?


Post-Thanksgiving bump.

@brunoadacosta brunoadacosta referenced this issue in DevInSantos/devinsantos-events Dec 3, 2012

shoulda-matchers não está funcionando #1


I had this same problem a while ago on a rack project. I solved it by stoping loading shoulda-matchers at Gemfile and loading it inside spec_helper.rb


  gem 'shoulda-matchers', :require => false


  require 'shoulda-matchers'

Hope this helps.


@plribeiro3000 Tried that to no avail.


This seems to be fixed by the merge to master resulting from thoughtbot/shoulda#221 (comment).

thoughtbot, inc. member

Fantastic! I'll close this then.

@gabebw gabebw closed this Dec 27, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment