Как проверить обратные вызовы ActiveRecord с помощью RSpec?

Как проверить следующий пример?

class Post < ActiveRecord::Base
  belongs_to :discussion, touch: true
end

Ответы

Ответ 1

Вы можете установить ожидаемое сообщение:

it "should touch the discussion" do
  post = Factory.build(:post)
  post.discussion.should_receive(:touch)
  post.save!
end

В этих примерах используется Factory Девушка, но вы также можете использовать приспособления или макеты.

Ответ 2

Во-первых

Если все, что вы пытаетесь сделать, - утверждать, что параметр touch: true установлен в вашей ассоциации, вы можете просто сделать следующее:

describe Post do
  it { should belong_to(:discussion).touch(true) }
end

Во-вторых

Для тестирования обратных вызовов в общем, читайте дальше.

Все остальные ответы здесь имеют два недостатка:

  • Они требуют попадания в базу данных, которая может быть медленной.

  • Они не определяют, какой обратный вызов вызывается во время save!

Вместо этого используйте "Ответчики обратного вызова" , который не требует попадания в базу данных, и вы можете указать, какие callback вы проверяете существование.

Установка

Установите "Ответчики обратного вызова" с помощью Bundler:

group :test do
  gem "shoulda-callback-matchers", "~> 1.0"
end

Использование

it { should callback(:some_method).after(:save) }

Благодарим Beat за запись этой большой библиотеки.

Ответ 3

Вы можете издеваться над вызовом # touch или проверить влияние своего обратного вызова на него.

it "should touch the discussion" do
  original_updated_at = @discussion.updated_at
  @post.save!
  @post.discussion.updated_at.should_not_be == original_updated_at
end