如何在没有关联数据库表的情况下RSpec共享ActiveRecord模块?

jan*_*hii 14 activerecord rspec ruby-on-rails

使用RSpec 2.6/Rails 3.1/Postgres:

我正在编写一个支持模块(在我的lib /中),任何AR模型都可以包含.我想为这个模块编写规范.它需要包含在AR :: Base模型中,因为它在包含时加载关联并依赖于某些AR方法,但我不想在为此模块编写rspec时使用我现有的模型.

我只想创建一个任意的AR模型,但显然它不会在数据库中关联一个表,而AR正在死亡.这是我想要做的事情:

class SomeRandomModel < ActiveRecord::Base
  include MyModule

  # simulate DB attributes that MyModule would be using
  attr_accessor :foo, :bar, :baz 
end

describe SomeRandomModel do
  it '#some_method_in_my_module' do
    srm = SomeRandomModel.new(:foo => 1)
    srm.some_method_in_my_module.should eq(something)
  end
end
Run Code Online (Sandbox Code Playgroud)

当然,我在postgres中得到一些关于不存在的关系的错误.

谢谢你的帮助!

p11*_*00i 16

还有一种方法可以使用rpsecs来解决这个问题shared_examples_for,我在代码片段中提到了一些技巧,但是有关更多信息,请参阅relishapp-rspec-guide.

有了这个,您可以在包含它的任何类中测试您的模块.所以你真的在测试你在应用程序中使用的内容.

我们来看一个例子:

# Lets assume a Movable module
module Movable
  def self.movable_class?
    true
  end

  def has_feets?
    true
  end
end

# Include Movable into Person and Animal
class Person < ActiveRecord::Base
  include Movable
end

class Animal < ActiveRecord::Base
  include Movable
end
Run Code Online (Sandbox Code Playgroud)

现在让我们为我们的模块创建规范: movable_spec.rb

shared_examples_for Movable do
  context 'with an instance' do
    before(:each) do
      # described_class points on the class, if you need an instance of it: 
      @obj = described_class.new

      # or you can use a parameter see below Animal test
      @obj = obj if obj.present?
    end

    it 'should have feets' do
      @obj.has_feets?.should be_true
    end
  end

  context 'class methods' do
    it 'should be a movable class' do
      described_class.movable_class?.should be_true
    end
  end
end

# Now list every model in your app to test them properly

describe Person do
  it_behaves_like Movable
end

describe Animal do
  it_behaves_like Movable do
    let(:obj) { Animal.new({ :name => 'capybara' }) }
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这个答案应该是接受的答案.这是处理模块规范的正确方法. (4认同)

gog*_*n13 15

我正面临着类似的问题,经过大量的谷歌搜索后,我已经决定在我的RSpec测试中设置和拆除表格.这是我一直在使用的片段:

describe "stuff you are testing do" do

  before :all do
    m = ActiveRecord::Migration.new
    m.verbose = false  
    m.create_table :random_class do |t| 
      t.string :field_1
      t.integer :field_2
    end
  end

  after :all do
    m = ActiveRecord::Migration.new
    m.verbose = false
    m.drop_table :random_class
  end

  class RandomClass < ActiveRecord::Base
    attr_accessible :field_1, :field_2
  end

  # Your regular RSpec before(:each) blocks and tests
  # ...

  # e.g.
  it "should be able to use RandomClass" do
    rc = RandomClass.create! :field_1 => "hello", :field_2 => 5
    rc.field_1.should == "hello"
    rc.field_2.should == 5
  end

end
Run Code Online (Sandbox Code Playgroud)

我并不喜欢这个解决方案,但它确实有效.希望对某人有帮助!无论是那个还是激励他们发布实现这一目标的最佳方式.

:)

  • 这可能有效,但这不是一个好的解决方案.您不必使用rspecs shared_examples或http://stackoverflow.com/questions/16453266/rails-rspec-testing-concerns-class-methods查看burninggrammas答案以获得更好的解决方案 (2认同)