使用rspec测试'where'子句

时间:2014-01-27 17:03:48

标签: sql ruby-on-rails rspec tdd

我一直在学习使用rspec。 我必须测试这个:

Book.where(old:false, id:user.collections.select(:book_id).group(:book_id).map(&:book_id)).map{|b|[b.name, b.id] }

我已经做的是:

@user = Fabricate(:user)
@book1 = Fabricate(:book, old:false)
@book2 = Fabricate(:book, old:true)
@collection = Fabricate(:collection, book_id:@book1.id)
@collection2 = Fabricate(:collection, book_id:@book2.id)
@user.collections << @book1 << @book2
@books = Book.where(old:false, id:@user.collections.select(:book_id).group(:book_id).map(&:book_id)).map{|b|[b.name, b.id]}

.....

it "books" do
      subject[:filter].should == @books.map{|d| [d.name, d.id]}
end

它期待一本书,但我得到了0.我忘记了什么吗? 提前感谢任何想法和帮助!

1 个答案:

答案 0 :(得分:1)

您的代码非常难以理解且难以测试。您应该将执行拆分为更小的方法。

Book.where(old:false, id:user.collections.select(:book_id).group(:book_id).map(&:book_id)).map{|b|[b.name, b.id] }

可能是

class Book
  def self.find_books_with_name(ids)
    where(old: false, id: ids).map { |b| [b.name, b.id] }
  end
end

然后你可以用:

来调用它
Book.find_books_and_name(user.collections.select(:book_id).group(:book_id).map(&:book_id))

对我来说同样疯狂。添加到您的用户模型和集合模型,如

class Collection
  def self.book_ids
    select(:book_id).group(:book_id).map(&:book_id)
  end
end

现在你有了

Book.find_books_and_name(user.collections.book_ids)

现在您可以(并且您应该)分别测试每种方法。失败将更容易发现,测试本身将更加简单,没有与各种模型和记录的耦合。