简体   繁体   中英

How to prevent RSpec from running specs twice in Rails plugin with dummy app?

I'm writing a Rails extension. To test it, I use RSpec. In order to make models to test the plugin on, I use a pregenerated dummy app:

rails plugin new yaffle --dummy-path=spec/dummy --skip-test --full

I have a few tests. When I call them, they run twice.

> # I have 4 tests in app total
> rspec
> 8 examples, 0 failures
> rspec spec/yaffle/active_record/acts_as_yaffle_spec.rb
> 4 examples, 0 failures
> rspec spec/yaffle/active_record/acts_as_yaffle_spec.rb:4
> 2 examples, 0 failures

This is how my files look like:

# lib/yaffle.rb
Gem.find_files('yaffle/**/*.rb').each { |path| require path }

module Yaffle
  # Your code goes here...
end
# spec/spec_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../dummy/config/environment", __FILE__)

RSpec.configure do |config|
  config.example_status_persistence_file_path = '.rspec_status'
  config.disable_monkey_patching!
end
# spec/dummy/config/environment.rb
# Load the Rails application.
require_relative 'application'

# Initialize the Rails application.
Rails.application.initialize!
# spec/yaffle/active_record/acts_as_yaffle_spec.rb

require "spec_helper"

RSpec.describe "Acts as yaffle" do
  def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
    assert_equal "last_squawk", Hickwall.yaffle_text_field
  end

  def test_a_wickwalls_yaffle_text_field_should_be_last_tweet
    assert_equal "last_tweet", Wickwall.yaffle_text_field
  end
end
# spec/dummy/config/application.rb
require_relative 'boot'

require "rails/all"
Bundler.require(*Rails.groups)
require "yaffle"

module Dummy
  class Application < Rails::Application
    config.load_defaults 6.0
  end
end

Also, I noticed that only files with require "spec_helper" are duplicated

So, what am I doing wrong? And, if it's a bug, how to work around it?

The cause

It was caused by this line:

Gem.find_files('yaffle/**/*.rb').each { |path| require path }

Apparently, Gem.find_files gets all files in gem directory that match that pattern - not only the files relative to gem root. So, yaffle/**/*.rb means both files in <GEM_ROOT>/lib/yaffle/... and <GEM_ROOT>/spec/lib/yaffle/... .

https://apidock.com/ruby/v1_9_3_392/Gem/find_files/class

Fix

I fixed it by requiring all files explicitly:

require 'lib/yaffle/active_record/acts_as_yaffle'
require 'lib/yaffle/active_record/has_fleas'

It's also possible to just require all files from that directory:

Dir["lib/yaffle/active_record/**/*.rb"].each {|file| require file }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM