Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapping ActiveRecord test causes it to fail (no records found) #13

Open
hansondr opened this issue Jan 6, 2017 · 3 comments
Open

Wrapping ActiveRecord test causes it to fail (no records found) #13

hansondr opened this issue Jan 6, 2017 · 3 comments

Comments

@hansondr
Copy link

hansondr commented Jan 6, 2017

I created a script to demonstrate this behavior:

#!/usr/bin/env ruby

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required.  Please update your bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"
  gem "activerecord", "4.2.7.1"
  gem "mysql2", "0.4.5"
  gem "database_cleaner", "1.5.3"
  gem "rspec", "3.5.0"
end

require "active_record"
require "rspec"
require "rspec/autorun"
require "database_cleaner"

ActiveRecord::Base.establish_connection(
  adapter: "mysql2",
  username: "root",
  password: "password",
  host: "localhost",
  database: "ft_test"
)
ActiveRecord::Base.connection.recreate_database "ft_test"

ActiveRecord::Schema.define do
  create_table :widgets, force: true do |t|
    t.string "description", limit: 255
  end

  add_index "widgets", ["description"], name: "widgets_description_fts", type: :fulltext
end

class Widget < ActiveRecord::Base
  def self.text_search(query)
    where("MATCH(description) AGAINST(:query)", query: query)
  end

  def self.like_search(query)
    where("description like ?", "%#{query}%")
  end
end

RSpec.configure do |config|
  config.default_formatter = "doc"
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end
  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end
end

RSpec.describe Widget, type: :model do
  describe ".text_search" do
    after(:all) { Widget.delete_all }
    it "fails when cleaning with start/clean" do
      DatabaseCleaner.start

      text_search_test

      DatabaseCleaner.clean
    end

    it "fails when cleaning with block" do
      DatabaseCleaner.cleaning do
        text_search_test
      end
    end

    it "succeeds with manual cleaning (fails at random, unless it is first or the only test run)" do
      Widget.delete_all

      text_search_test

      Widget.delete_all
    end
  end

  describe ".like_search" do
    it "succeeds when cleaning with start/clean" do
      DatabaseCleaner.start

      like_search_test

      DatabaseCleaner.clean
    end

    it "succeeds when cleaning with block" do
      DatabaseCleaner.cleaning do
        like_search_test
      end
    end

    it "succeeds with manual cleaning" do
      Widget.delete_all

      like_search_test

      Widget.delete_all
    end
  end

  private

  def create_widgets
    Widget.create()
    match = Widget.create(description: "The quick brown fox jumps over the lazy dog")
    Widget.create()

    match
  end

  def text_search_test
    match = create_widgets
    expect(Widget.text_search("fox")).to contain_exactly match
  end

  def like_search_test
    match = create_widgets
    expect(Widget.like_search("fox")).to contain_exactly match
  end
end
@hansondr
Copy link
Author

hansondr commented Jan 7, 2017

Expected output:

Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/.
Resolving dependencies...
Using i18n 0.7.0
Using json 1.8.3
Using minitest 5.10.1
Using thread_safe 0.3.5
Using builder 3.2.2
Using arel 6.0.4
Using database_cleaner 1.5.3
Using diff-lcs 1.2.5
Using mysql2 0.4.5
Using rspec-support 3.5.0
Using bundler 1.13.7
Using tzinfo 1.2.2
Using rspec-core 3.5.4
Using rspec-expectations 3.5.0
Using rspec-mocks 3.5.0
Using activesupport 4.2.7.1
Using rspec 3.5.0
Using activemodel 4.2.7.1
Using activerecord 4.2.7.1
-- create_table(:widgets, {:force=>true})
   -> 0.0701s
-- add_index("widgets", ["description"], {:name=>"widgets_description_fts", :type=>:fulltext})
   -> 0.4454s

Randomized with seed 46507

Widget
  .text_search
    succeeds with manual cleaning (fails at random, unless it is first or the only test run)
    fails when cleaning with start/clean (FAILED - 1)
    fails when cleaning with block (FAILED - 2)
  .like_search
    succeeds when cleaning with block
    succeeds when cleaning with start/clean
    succeeds with manual cleaning

Failures:

  1) Widget.text_search fails when cleaning with start/clean
     Failure/Error: expect(Widget.text_search("fox")).to contain_exactly match
     
       expected collection contained:  [#<Widget id: 5, description: "The quick brown fox jumps over the lazy dog">]
       actual collection contained:    []
       the missing elements were:      [#<Widget id: 5, description: "The quick brown fox jumps over the lazy dog">]
     # ./mysql2_full_text_issue.rb:122:in `text_search_test'
     # ./mysql2_full_text_issue.rb:66:in `block (3 levels) in <main>'

  2) Widget.text_search fails when cleaning with block
     Failure/Error: expect(Widget.text_search("fox")).to contain_exactly match
     
       expected collection contained:  [#<Widget id: 8, description: "The quick brown fox jumps over the lazy dog">]
       actual collection contained:    []
       the missing elements were:      [#<Widget id: 8, description: "The quick brown fox jumps over the lazy dog">]
     # ./mysql2_full_text_issue.rb:122:in `text_search_test'
     # ./mysql2_full_text_issue.rb:73:in `block (4 levels) in <main>'
     # ./mysql2_full_text_issue.rb:72:in `block (3 levels) in <main>'

Finished in 0.68526 seconds (files took 1.07 seconds to load)
6 examples, 2 failures

Failed examples:

rspec ./mysql2_full_text_issue.rb:63 # Widget.text_search fails when cleaning with start/clean
rspec ./mysql2_full_text_issue.rb:71 # Widget.text_search fails when cleaning with block

Randomized with seed 46507

@hansondr
Copy link
Author

hansondr commented Jan 9, 2017

I've temporarily sidestepped this issue but selectively disabling database cleaner on specs in which this error is present:

#  spec/support/database_cleaner.rb
RSpec.configure do |config|
  # ...
  config.before(:each) do
    DatabaseCleaner.start unless manually_cleaned?
  end

  config.append_after(:each) do
    DatabaseCleaner.clean unless manually_cleaned?
  end

  def manually_cleaned?
    self.class.metadata[:manually_cleaned]
  end
end

Then to skip automatic cleaning in a spec:

RSpec.describe Widget, manually_cleaned: true do
  # ...
end

@botandrose botandrose transferred this issue from DatabaseCleaner/database_cleaner Feb 18, 2020
@dnstufff
Copy link

Try this solution. I think it might be what you are searching for: https://stackoverflow.com/a/69724116/537648

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants