Rspec тестирование возвращения столбца counter_cache 0
Уже несколько дней я пытаюсь докопаться до сути того, что должно быть очень легко сделать... Однако я все еще очень плохо знаком с миром рельсов и рубинов, и я просто не могу разобраться с этим...:п
В любом случае, у меня проблема в том, что у меня есть несколько столбцов: counter_cache в моей модели, которые работают очень хорошо при тестировании их вручную. Однако я хочу сделать TDD, и я не могу шов, чтобы проверить их в rspec по какой-то неизвестной причине??
В любом случае, вот пример моей модели (пользователя, комментарии и медиа):
class User < ActiveRecord::Base
has_many :comments
has_many :media, dependent: :destroy
end
class Comment < ActiveRecord::Base
attr_accessible :content, :user_id
belongs_to :commentable, polymorphic: true, :counter_cache => true
belongs_to :user, :counter_cache => true
validates :user_id, :presence => true
validates :content, :presence => true, :length => { :maximum => 255 }
end
class Medium < ActiveRecord::Base
attr_accessible :caption, :user_id
belongs_to :user, :counter_cache => true
has_many :comments, as: :commentable
validates :user_id, presence: true
validates :caption, length: { maximum: 140 }, allow_nil: true, allow_blank: true
default_scope order: 'media.created_at DESC'
end
Вот примеры настройки схемы таблицы:
create_table "users", :force => true do |t|
t.integer "comments_count", :default => 0, :null => false
t.integer "media_count", :default => 0, :null => false
end
create_table "comments", :force => true do |t|
t.text "content"
t.integer "commentable_id"
t.string "commentable_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "user_id"
end
create_table "media", :force => true do |t|
t.integer "user_id"
t.string "caption"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "comments_count", :default => 0, :null => false
end
А теперь вот пример примера rspec, который я пробовал:
require 'spec_helper'
describe "Experimental" do
describe "counter_cache" do
let!(:user) { FactoryGirl.create(:user)}
subject { user }
before do
@media = user.media.create(caption: "Test media")
end
its "media array should include the media object" do
m = user.media
m.each do |e|
puts e.caption # Outputting "Test media" as expected
end
user.media.should include(@media) #This works
end
it "media_count should == 1 " do # This isnt working?
puts user.media_count #Outputting 0
user.media_count.should == 1
end
end
end
И, наконец, сообщение об ошибке, которое дает мне rspec:
Failures:
1) Experimental counter_cache media_count should == 1
Failure/Error: user.media_count.should == 1
expected: 1
got: 0 (using ==)
# ./spec/models/experimental_spec.rb:24:in `block (3 levels) in <top (required)>'
Finished in 0.20934 seconds
2 examples, 1 failure
Также обратите внимание, что это происходит для всех моих столбцов counter_cache во всех моих моделях. Я также попробовал несколько различных способов проверить это, но все они возвращают вышеуказанное сообщение об ошибке.
Очень надеюсь, что кто-то может помочь мне с этим.:)
Спасибо заранее! Люк
1 ответ
counter_cache
обновляется в базе данных напрямую. Это не повлияет на копию модели, которую вы загрузили в память, поэтому вам необходимо перезагрузить ее:
it "media_count should == 1 " do
user.reload
user.media_count.should == 1
end
Но я не думаю, что так я бы это проверил. Как у вас есть, ваш тест очень тесно связан с установочным кодом, который, кажется, не должен быть там вообще. Как насчет чего-то подобного для отдельной спецификации:
it "has a counter cache" do
user = FactoryGirl.create(:user)
expect {
user.media.create(caption: "Test media")
}.to change { User.last.media_count }.by(1)
end
Для testng counter_cache вы можете использовать гем Shoulda-Matchers, есть метод из коробки