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
books_present = false
,authors = [(Double "Author_1001"), (Double "Author_1001")]
authors.destroy_all = []
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)