代码之家  ›  专栏  ›  技术社区  ›  stillmotion

Rails 3和Rspec中的存根链式查询

  •  14
  • stillmotion  · 技术社区  · 14 年前

    我正在尝试测试一个基于一系列其他作用域的作用域。(“公共物流”见下文)。

    scope :public, where("entries.privacy = 'public'")
    scope :completed, where("entries.observation <> '' AND entries.application <> ''")
    scope :without_user, lambda { |user| where("entries.user_id <> ?", user.id) }
    scope :public_stream, lambda { |user| public.completed.without_user(user).limit(15) }
    

    使用这样的测试:

        it "should use the public, without_user, completed, and limit scopes" do
          @chain = mock(ActiveRecord::Relation)
          Entry.should_receive(:public).and_return(@chain)
          @chain.should_receive(:without_user).with(@user).and_return(@chain)
          @chain.should_receive(:completed).and_return(@chain)
          @chain.should_receive(:limit).with(15).and_return(Factory(:entry))
    
          Entry.public_stream(@user)
        end
    

    Failure/Error: Entry.public_stream(@user)
    undefined method `includes_values' for #<Entry:0xd7b7c0>
    

    似乎includes_values是ActiveRecord::Relation对象的一个实例变量,但是当我尝试存根它时,仍然收到相同的错误。我想知道是否有人有过stub Rails 3新的链式查询的经验?我可以在2.x的find hash上找到一些讨论,但是没有关于如何测试当前内容的内容。

    4 回复  |  直到 14 年前
        1
  •  21
  •   astjohn    13 年前

    我用rspec stub_chain 为了这个。您可能可以使用以下内容:

    scope :uninteresting, :conditions => ["category = 'bad'"],
                          :order => "created_at DESC"
    

    控制器

    @some_models = SomeModel.uninteresting.where(:something_else => true)
    

    规格

    SomeModel.stub_chain(:uninteresting, :where) {mock_some_model}
    
        2
  •  3
  •   user1094125    10 年前

    答案同上。

    SomeModel.stub_chain(:uninteresting, :where) {mock_some_model}
    

    Rspec 3版本:

    allow(SomeModel).to receive_message_chain(:uninteresting).and_return(SomeModel.where(nil))
    

    参考:

    https://relishapp.com/rspec/rspec-mocks/docs/method-stubs/stub-a-chain-of-methods

        3
  •  1
  •   zealoushacker    12 年前

    您应该只为您自己编写的代码编写单元测试(如果您练习TDD,这应该是第二种性质)Rails附带了自己的完整单元测试套件,用于其构建的功能没有必要复制它。

    至于抛出的错误,我认为您的问题是:

    @chain.should_receive(:limit).with(15).and_return(Factory(:entry))
    

    你希望链子返回 Factory ,这实际上是 ActiveRecord ,但实际上 every relation returns yet another ActiveRecord::Relation .

    请记住,在显式迭代之前,作用域实际上不会返回预期的记录。而且,这段关系的记录 从未 返回单个记录。他们将 总是 返回空数组或包含记录的数组。

        4
  •  0
  •   thomasfedb    13 年前

    it "should use the public, without_user, completed, and limit scopes" do
      @chain = Entry
      @chain.should_receive(:public).and_return(@chain.public)
      @chain.should_receive(:without_user).with(@user).and_return(@chain.without_user(@user))
      @chain.should_receive(:completed).and_return(@chain.completed)
      @chain.should_receive(:limit).with(15).and_return(Factory(:entry))
    
      Entry.public_stream(@user)
    end