Работая над выполнением главы 10 учебного пособия Rails, которое относится к тестированию разбиения на страницы микропоставок, я не могу понять, почему мои тесты ломаются, когда я их делаю с before(:all)
и after(:all)
как ниже. Даже просто меняя его на before(:each)
, он работает, поэтому это не переменная экземпляра. (хотя я могу также заставить его работать, не используя экземпляр, и создать user
, предоставленный let
)не уверен, почему изменение до того, как все разрывает этот тест
Я просто пытаюсь сделать это надлежащим образом. Выполнение этого раз (то есть, :all
) кажется правильным для этого. Что мне не хватает?
Я пробовал stop_and_open_page
- он не показывает никаких микропотоков, когда я использую :all
, только в противном случае (с :each
). Однако, проверяя либо мою переменную экземпляра, либо user
(при попытке этого сделать с let
) с binding.pry
в консоли - она имеет микросообщения все время, даже когда я указываю :all
.
Я думаю, что это связано с тем, что я не загружаю ассоциацию, когда использую :all
, но я не могу придумать причину, так как она работает иначе на сайте образца и в тестах, когда не используется :all
.
Любые идеи?
P.S. У меня есть побочный вопрос: у меня есть отношение, установленное в моей модели User
, например, has_many :microposts, dependent: :destroy
, но когда я делаю эти тесты с помощью метода переменных экземпляра, приведенного ниже, я должен явно называть delete_all
на микропостах, в противном случае они остаются в тестовом db после (даже если пользователь удаляется). Я пропустил что-то там очевидное или каскадное уничтожение не работает, когда пользователь создан через Factory Girl?
UPDATE: Благодаря @Jesper я поймал причину, по которой after (: all) не удалял связанные микропосты. Код обновлен, чтобы отразить это.
subject { page }
let(:user) { FactoryGirl.create(:user) }
before { valid_signin user }
...
describe "micropost pagination" do
before(:all) do
@user_with_many_posts = FactoryGirl.create(:user, email: "[email protected]")
@user_with_many_posts.save
31.times { FactoryGirl.create(:micropost, user: @user_with_many_posts) }
valid_signin @user_with_many_posts
visit root_path
end
after(:all) do
@user_with_many_posts.destroy
end
it { should have_selector('div.pagination') }
it "should list each micropost" do
@user_with_many_posts.microposts.paginate(page: 1).each do |mp|
expect(page).to have_selector('li', text: mp.content)
end
end
end
Причина, по которой вы иждивенцы не уничтожены, заключается в том, что 'delete' пропускает обратные вызовы. Другими словами, обратные вызовы, необходимые для уничтожения связанных моделей, никогда не называются. Вместо этого используйте 'destroy'. – Jesper
Я вижу, хороший улов. Я помню, что читал это, но когда я написал тест, у меня был метод HTTP DELETE. Итак, теперь после (: all) это происходит, и он удаляет все связанные тестовые микропосты: 'after (: all) do @ user_with_many_posts.destroy end' – equalizer
Хорошо, пост обновлен, чтобы отобразить правильные 'after (: все) '. Теперь, если у кого-то есть представление о том, почему этот тест в целом работает только тогда, когда это делается как ': each' ... – equalizer