【问题标题】:RSpec: how can I mixin a module into RSpec test?RSpec:如何将模块混入 RSpec 测试?
【发布时间】:2013-12-11 16:36:02
【问题描述】:

在我的应用中,当用户分享某些内容时,他的评分会增加。当他尝试分享某样东西两次时,他将不会在第二次尝试时获得额外评分。对于应用程序,共享回调是由客户端用JS触发的,所以它只是一个常规的GET请求。所以,我需要测试这个功能。这简单。但是我有几个部分有这种行为。该部分中的每个控制器都有名为“rating_from_share”的方法,因此测试非常相似。我认为在混合中提取该测试并将它们包含在应有的位置是个好主意,但我无法弄清楚,我该怎么做。 那么,在 RSpec 测试中包含与 RSpec 的混合是真的吗?也许某种元编程可以解决这个问题?

附: “rating_from_share”方法的实现并不完全相同,只是输出结果,所以我不能将它聚合到一个超类并在这里测试它们。

编辑:

根据 Vimsha 的回答,我应该这样做吗?

Module Share
  def share
    it 'should be fun'
      expect(@fun.isFun?).toBe == 'yup' # the @fun is declared in ShareTest
    end
  end
end

describe "Share Test" do
   extend Share
   before :each do
     @fun = Fun.new
   end
   it 'should do test' do
     share # call method from Share module, which has real RSpec code?
   end
end

代码就写在这里,我只是想明白。

【问题讨论】:

    标签: ruby-on-rails rspec mixins


    【解决方案1】:

    RSpec 中的一个常见做法是将此类逻辑存储在spec/support 下。例如:

    # spec/support/ratings_macros.rb
    module RatingsMacros
      ...
    end
    

    然后您需要从您的spec_helper 加载它:

    # spec/spec_helper.rb
    ...
    RSpec.configure do |config|
      ...
      config.include RatingsMacros
    

    您现在可以在测试中调用RatingsMacros 模块中定义的所有方法。

    【讨论】:

    • 这不会包括所有测试的模块吗?
    • 是的。这通常不是问题。
    【解决方案2】:

    您可以使用shared examples。

    这些通常保存在spec/support 下并通过spec_helper.rb 加载。请务必阅读文档以了解如何加载共享代码——它不会自动为您执行。

    一旦它们被定义,你可以像这样包含它们:

    # spec/support/decorated_model.rb
    shared_examples "decorated_model" do
      it "can be decorated" do
        subject.should respond_to?(:decorate)
      end
    end
    
    # my_class_spec.rb
    describe MyClass do
      it_behaves_like "decorated_model"
    end
    

    【讨论】:

      【解决方案3】:
      module Share
        def share
        end
      end
      
      describe "Share Test" do
         extend Share
      end
      

      您可以直接在测试中调用模块的方法

      【讨论】:

      【解决方案4】:

      其他答案用模块的方法污染了测试,或者涉及编写一个虚拟类。此解决方案使用内置的 double 对象作为一次性对象来扩展模块的方法。

      RSpec.describe Share do
        describe '#share' do
          subject { double.extend(described_class) }
        end
      
        it 'does something cool' do
          expect(subject.share).to eq 'something_cool'
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-05
        • 2012-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多