Testing a concern / module that uses ActiveRecord

后端 未结 4 540
你的背包
你的背包 2020-12-30 04:25

SCENARIO I have extracted a concern called Taggable. It\'s a module that allows any model to support tagging. I have included

相关标签:
4条回答
  • 2020-12-30 05:03

    I would suggest having DummyClass be a generic ActiveRecord::Base child with very little custom code besides just include Taggable, so that you would be isolating your concern module as much as possible but still being an AR class. Avoiding the use of one of your "real" classes like User still isolates you from any other code in those classes, which seems valuable.

    So something like this:

    class DummyClass < ActiveRecord::Base; end
    
    describe Taggable do
      before do
        @dummy_class = DummyClass.new
      end
      ...
    end
    

    Since your DummyClass may need to actually interact with the DB to test things like associations, you may need to create temporary tables in the DB during testing. The temping Ruby gem may be able to help with that, since its designed to create temporary ActiveRecord models and their underlying database tables.

    Temping allows you to create arbitrary ActiveRecord models backed by a temporary SQL table for use in tests. You may need to do something like this if you're testing a module that is meant to be mixed into ActiveReord models without relaying on a concrete class.

    0 讨论(0)
  • 2020-12-30 05:06

    Here is my solution of similar problem:

    describe Taggable do
      subject { mock_model('User').send(:extend, Taggable) }
    
      it { should have_many(:tags) }
      ...
    
      describe "#tag" do
        ...
      end
    end
    

    In fact mock_model('User') can mock any existent model in the system.

    This is not an ideal solution but at least it's clear and mocks everything.

    Note: mock_model (AR mocks) were extracted to rspec-activemodel-mocks in rspec 3.0.
    Also you need to use shoulda-matchers for associations matchers.

    0 讨论(0)
  • 2020-12-30 05:08

    I went with using ActiveRecord Tableless rather than Temping gem, which seems to be a little out of date at the moment.

    I set up my test up exactly the same as Stuart M has in his answer but included the has_no_table helper method and columns required in my DummyClass.

    class DummyClass < ActiveRecord::Base
      # Use ActiveRecord tableless
      has_no_table
      # Add table columns
      column :name, :string
      # Add normal ActiveRecord validations etc
      validates :name, :presence => true
    end   
    

    This worked for what I needed to test, which was a module that extended ActiveRecord::Base with a few additional methods, but I haven't tried it with any has_many associations so it still might not help with what you wanted to test.

    0 讨论(0)
  • 2020-12-30 05:08

    As suggested in @StuartM's answer, using the temping gem worked for me:

    # test.rb/spec.rb
    Temping.create :dummy_class do
      include Taggable
    end
    
    describe Taggable do
      before do
        @dummy = DummyClass.new
      end
      ...
    end
    
    0 讨论(0)
提交回复
热议问题