在不命中数据库的情况下测试Active Record Callback

时间:2017-09-07 02:10:41

标签: ruby-on-rails activerecord rspec callback

class Book  < ActiveRecord::Base 
  belongs_to :author
end

class Author < ActiveRecord::Base  
  belongs_to :publisher
  has_many   :books
end  

class Publisher < ActiveRecord::Base
  before_destroy :remove_empty_author
  has_many   :authors, dependent: destroy_all

  def remove_empty_author
    books_present = authors.map(&:book).all? { |book| book.present? }
    authors.destroy_all unless books_present
  end
end

class PublishersController < ApplicationController
  def destroy
    @publisher = Publisher.find(params[:id].to_i)
    @publisher.destroy # for simplicity I only show the destroy call
  end
end

方案

这离工作太近了! 我有一个控制器测试 我想在不创建数据库条目或查询数据库的情况下测试以下内容:
1. remove_empty_author回调称为&amp;如果我删除它&amp; before_destroy测试抱怨。 2.对作者要求销毁。

注意:
我不想测试remove_empty_author方法的细节。这将在模型单元测试中进行测试,只有在作者没有书籍时才删除出版商和所有作者。

我尝试了什么

describe "#delete," do
  context "Publisher has no authors," do
    before do
     author = mock_model("Author", book: [])
     @publisher = Publisher.new(id: 2, authors: [author, author])
     current_publisher = mock_model("Publisher", id: 1)
     allow(Publisher).to receive(:find).and_return(@publisher)
     allow(controller).to receive(:current_publisher).and_return(current_publisher)
    end

    it "Controller calls destroy on Publisher" do
      expect_any_instance_of(Publisher).to receive(:destroy)
    end

    it "Publisher calls remove_empty_author" do
      expect_any_instance_of(Author).to receive(:destroy)
      @publisher.run_callbacks(:destroy) do
        false # Prevent active record from proceeding with destroy
      end
    end 
  end
 end

正在运作的事情

  1. 控制器调用销毁发布商测试工作。
  2. 测试成功进入remove_empty_author回调,其中
    books_present = false
    authors = [(Double "Author_1001"), (Double "Author_1001")] authors.destroy_all = []
  3. 我想要克服错误

    Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure } Exactly one instance should have received the following message(s) but didn't: destroy

    什么不起作用

    expect_any_instance_of(Author).to receive(:destroy)

0 个答案:

没有答案