在Rails / RSpec中存储私有控制器方法

时间:2014-10-03 06:12:30

标签: ruby-on-rails rspec mocking

这个简单的测试有问题:

book_spec.rb

let(:books_controller) { BooksController.new }

context "GET #index" do
  it "calls Book.all" do
    Book.should_receive(:all)
    book_controller.index
  end
end

books_controller.rb

def index
  respond_with books
end

private

def books
  @books ||= Book.all
end

我希望将对ActiveRecord的调用存根,以便它不需要与数据库交互并加速测试。但是我似乎无法做到这一点。

编辑:

抱歉忘记了最重要的一点!

 Failure/Error: book_controller.index
 NoMethodError:
   undefined method `variant' for nil:NilClass

1 个答案:

答案 0 :(得分:2)

通过实例化控制器来测试Rails中的控制器将很困难。大多数控制器测试使用Rspec的get方法调用控制器操作。尝试类似:

context "GET #index" do
  it "calls Book.all" do
    expect(Book).to receive(:all)
    get :index
  end
end

如果您真的不想触摸ActiveRecord,那么您可以通过将测试更改为以下内容来存储Book

let(:book) { double(:book, all: true) }

context "GET #index" do
  it "calls Book.all" do
    stub_const("Book", book) 
    expect(Book).to receive(:all)
    get :index
  end
end

然而,我并不认为你会在这里试图保留活跃记录,从而获得更多的速度提升。在运行测试时加载Rails环境是最大的时间开销 - 特别是对于小型测试套件。