Lorbin
Lorbin

Reputation: 23

rspec-rails+capybara NoMethodError:undefined method `create'

I'm learning ruby on rails, but I have a problem that I couldn't solve by myself. Any one can help me?

when I run:bundle exec rspec spec/models/user_spec.rb, I got this error:

Failure/Error: @user = create(:user)  NoMethodError:
       undefined method `create' for #<RSpec::ExampleGroups::User::PropertiesShouldNotNil:0xb807450>
     # ./spec/models/user_spec.rb:6:in `block (3 levels) in <top (required)>'

Gemfile:

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '5.0.0.rc2'
# Use mysql as the database for Active Record
gem 'mysql2'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails', '~> 2.3.0'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'alipay', '~> 0.10.0' #支付宝接口
gem 'capistrano-rails', :group => :development
gem 'capistrano-passenger', :group => :development
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
  # Access an IRB console on exception pages or by using <%= console %> in views
  #gem 'web-console', '~> 2.0'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'rspec-rails'
  gem "capybara"
end
group :development do
  gem 'web-console', group: :development
end

spec/rails_helper.rb:

ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara/rspec'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|

  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = true

  config.infer_spec_type_from_file_location!
end

app/models/user.rb

app/models/user.rb
  has_many :recipients
end

spec/models/user_spec.rb:

require 'rails_helper'

RSpec.describe User, type: :model do
  context "properties should not nil" do
    before do
      @user = create(:user)
    end

    subject{ @user }

    it { should respond_to(:name) }
    it { should respond_to(:passwd) }
  end
end

Upvotes: 2

Views: 1326

Answers (1)

Daniel Ruiz
Daniel Ruiz

Reputation: 620

This error is because the create method you are trying to call is usually defined in the FactoryGirl class. FactoryGirl is a Ruby gem that lets you define custom factories to instantiate your application-specific models.

As you may need to integrate this gem in your Rails app, I suggest that you use the factory_girl_rails gem. Simply add the gem declaration into the :test group of your Gemfile, like as follows:

group :development, :test do
  # Here go other gem declarations...
  gem 'factory_girl_rails'
end

Once you have included this gem in your project, you'll need to define the factories for your models (in this case, your User model) in order to specify the way you want your test instances to be built or created. I recommend you read this basic documentation on how to define factories with FactoryGirl (I read this doc over and over).

In advance, I could tell you that the factories are usually defined under the spec/factories folder (in cases like this, that you are using RSpec) and have a common structure. In this case, your Userfactory would be defined in a file like spec/factories/user.rb and be like:

FactoryGirl.define do
  factory :user do
    # Here you assign values to the different attributes, like:
    #  username "username"
    #  password "pass"
    #  ...
  end
end

I use the faker gem with FactoryGirl a lot, because it lets me create random values for names, telephone numbers, emails, etc in a way that are always different but make sense. Take a look at its documentation in case you are interested in it.

Hope these can help you solve your problem!

Upvotes: 1

Related Questions