14

我正在尝试测试我拥有的基于一系列其他范围的范围。(下面的“public_stream”)。

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 对象的实例变量,但是当我尝试存根它时,我仍然收到相同的错误。我想知道是否有人对 Rails 3 的新链式查询有经验?我可以找到一堆关于 2.x 的 find hash 的讨论,但没有关于如何测试当前内容的内容。

4

4 回答 4

21

stub_chain我为此使用rspec 。您可能可以使用类似的东西:

some_model.rb

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}
于 2011-01-19T01:02:11.340 回答
4

与上述相同的答案。

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

于 2014-04-16T16:56:08.543 回答
1

首先,您可能不应该测试内置的 Rails 功能。

你应该只为你自己编写的代码编写单元测试(如果你练习 TDD,这应该是第二天性)——Rails 为它的内置功能提供了自己的一套全面的单元测试——复制这个没有意义.

至于抛出的错误,我认为您的问题出在这一行:

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

您期望链返回 a Factory,这实际上是 的一个实例ActiveRecord,但实际上每个关系都返回另一个ActiveRecord::Relation

因此,您的期望本身是不正确的,并且可能确实导致了正在抛出的错误。

请记住,范围实际上不会返回您期望的记录,直到您明确地迭代它们。此外,关系的记录永远不会返回一条记录。它们将始终返回一个空数组或一个包含记录的数组。

于 2012-04-09T19:47:50.993 回答
0

尝试传递 Arel,因为它的作用域可能会丢失。

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
于 2011-01-03T18:48:20.903 回答