ruby-on-railsrspecfactory-bot

How do I install factory_bot_rails? I am using Rspec


I am trying to install factory_bot_rails to use with rspec.

I am working my way through Everyday Rails Testing with RSpec A practical approach to test-driven development, by Aaron Sumner, http://leanpub.com/everydayrailsrspec, published on 2024-10-10.

I was able to install factory_bot_rails on the cloned repo I downloaded from the book’s github site. However, when I try to use it on a repo I’m working on for work, I can’t get it to install.

Here’s what I tried:

$ bundle add factory_bot_rails
$ bundle install
$ rspec

I got the following error message (edit: added full stack trace)

An error occurred while loading ./spec/models/book_spec.rb.
Failure/Error: config.include FactoryBot::Syntax::Methods

NameError:
  uninitialized constant FactoryBot
# ./spec/support/factory_bot.rb:3:in `block in <top (required)>'
# ./spec/support/factory_bot.rb:2:in `<top (required)>'
# ./spec/rails_helper.rb:2:in `require'
# ./spec/rails_helper.rb:2:in `<top (required)>'
# ./spec/models/book_spec.rb:1:in `require'
# ./spec/models/book_spec.rb:1:in `<top (required)>'

An error occurred while loading ./spec/models/purchase_requests_spec.rb.
Failure/Error: config.include FactoryBot::Syntax::Methods

NameError:
  uninitialized constant FactoryBot
# ./spec/support/factory_bot.rb:3:in `block in <top (required)>'
# ./spec/support/factory_bot.rb:2:in `<top (required)>'
# ./spec/rails_helper.rb:2:in `require'
# ./spec/rails_helper.rb:2:in `<top (required)>'
# ./spec/models/purchase_requests_spec.rb:1:in `require'
# ./spec/models/purchase_requests_spec.rb:1:in `<top (required)>'
No examples found.

Finished in 0.00004 seconds (files took 0.08647 seconds to load)
0 examples, 0 failures, 2 errors occurred outside of examples

There is a model for “book” in my repo.

I also tried

$ rails generate factory_bot:model book

And got (edit adding full stack trace) )

jajames@IN-ULIB-CSTLAP5:~/projects/pda2(JJ-Rspec-factory-bot)$ rails generate factory_bot:model book
Traceback (most recent call last):
        31: from bin/rails:4:in `<main>'
        30: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        29: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        28: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/railties-7.0.3/lib/rails/commands.rb:18:in `<main>'
        27: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/railties-7.0.3/lib/rails/command.rb:48:in `invoke'
        26: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/railties-7.0.3/lib/rails/command/base.rb:87:in `perform'
        25: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
        24: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
        23: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
        22: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/railties-7.0.3/lib/rails/commands/generate/generate_command.rb:21:in `perform'
        21: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/railties-7.0.3/lib/rails/command/actions.rb:14:in `require_application_and_environment!'
        20: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/railties-7.0.3/lib/rails/command/actions.rb:22:in `require_application!'
        19: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        18: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
        17: from /home/jajames/projects/pda2/config/application.rb:7:in `<main>'
        16: from /home/jajames/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/bundler.rb:174:in `require'
        15: from /home/jajames/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:58:in `require'
        14: from /home/jajames/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:58:in `each'
        13: from /home/jajames/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:69:in `block in require'
        12: from /home/jajames/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:69:in `each'
        11: from /home/jajames/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:74:in `block (2 levels) in require'
        10: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
         9: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
         8: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot_rails-6.4.3/lib/factory_bot_rails.rb:1:in `<main>'
         7: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
         6: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
         5: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot_rails-6.4.3/lib/factory_bot_rails/railtie.rb:3:in `<main>'
         4: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
         3: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
         2: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot-6.4.5/lib/factory_bot.rb:25:in `<main>'
         1: from /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require': /home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot-6.4.5/lib/factory_bot/evaluator.rb:38: syntax error, unexpected (... (SyntaxError)
...method_missing(method_name, ...)
...                            ^~~
/home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot-6.4.5/lib/factory_bot/evaluator.rb:40: syntax error, unexpected ')'
...instance.send(method_name, ...)
...                              ^
/home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot-6.4.5/lib/factory_bot/evaluator.rb:42: syntax error, unexpected ')'
...nner.new.send(method_name, ...)
...                              ^
/home/jajames/.rvm/gems/ruby-2.7.2@pda/gems/factory_bot-6.4.5/lib/factory_bot/evaluator.rb:80: syntax error, unexpected end-of-input, expecting `end'

Also tried:

$ gem install factory_bot_rails
$ bundle install
$ rspec

https://github.com/thoughtbot/factory_bot_rails Same error message.

In Gemfile:

group :development, :test do
  gem 'rspec-rails', '~> 6.0.0'
  gem 'factory_bot_rails'
end

https://github.com/thoughtbot/factory_bot_rails

I tried both

$ factory_bot – version
$ factory_bot_rails –version

And got “factory_bot_rails: command not found”

What do I need to do different to install this?

I am using Ubuntu 22.04.5 on Windows 10 Enterprise, Rails 7.0.3, RSpec 3.12, Ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]


Here is spec/models/book_spec.rb

require 'rails_helper'

RSpec.describe Book, type: :model do
  it "is valid with a name and title" do
    book = Book.new(
      name: "jajames",
      title: "Emma",
      purchase: "ebook"
    )
  end

  it "requires a title" do
    book = Book.new(title: nil)

    expect(book).to be_invalid
    expect(book.errors[:title]).to_not include("can't be blank")
  end

  it "requires a name" do
    book = Book.new(name: nil)

    expect(book).to be_invalid
    expect(book.errors[:name]).to_not include("can't be blank")
  end

  it "requires a purchase" do
    book = Book.new(purchase: nil)

    expect(book).to be_invalid
    expect(book.errors[:purchase]).to_not include("can't be blank")
  end

end

No book factory was created.

What is a stack trace please? I am not a very advanced programmer.

Here is the code for config>application.rb. Did I put the config.generators code in the right place?

require_relative "boot"

require "rails/all"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Pda2
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 7.0

    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    # config.eager_load_paths << Rails.root.join("extras")

    # Custom configurations go here
    config.pda = config_for(:pda)
  end

  config.generators.system_tests = nil
  config.generators do |g|
    g.test_framework :rspec, fixtures: true, views: false, view_specs: false, helper_specs: false, routing_specs: false, controller_specs: false, request_specs: false
    g.fixture_replacement :factory_bot, dir: 'spec/factories'
    g.stylesheets false
    g.javascripts false
    g.helper false
  end
end

When I try Anton Bodganov's suggestion, I get the same error as "$ bundle add factory_bot_rails" (edited: I was in wrong folder)

when I try to generate a factory (I think that's what that's called)I get the same message as above $ rails generate factory_bot:model book


Solution

  • Your issue is that the version of factory_bot you are using leverages Ruby 3.0 syntax for argument forwarding but you are running Ruby 2.7.2.

    Options:

    1. RECOMMENDED upgrade your ruby to 3.3. Ruby 2.7 reached End of Life on March 31, 2023 and is no longer receiving support or security patches. 3.3 is the most recent stable branch.

    2. Downgrade factory_bot in your Gemfile. You can do this one of 2 ways:

      • Either update the current line for factory_bot_rails to read gem 'factory_bot_rails', '6.2.0'; or
      • Add gem 'factory_bot', '6.4.3' (which is the last version to use 2.7 compatible syntax)