0

Working through the exercise of Chapter 10 of the Rails Tutorial which pertains to testing pagination of micro posts, I cannot figure out why my tests break when I do them with before(:all) and after(:all) as below. Even just changing it to before(:each), it works, so it's not the instance variable. (although I can also get it to work not using the instance, and building up the user provided by let)

I am just trying to do this the proper way. Doing it once (i.e., :all) seems right for this. What am I missing?

I've tried stop_and_open_page - it shows no microposts when I use :all, only otherwise (with :each). However, by inspecting either my instance variable or user (when trying it that way with the let) with binding.pry in the console - it has the microposts all times, even when I do specify :all.

I am thinking it's something to do with not loading the association when I use :all, but I can't think of a reason, since it works otherwise in the sample site and in the tests when not using :all.

Any ideas?

P.S. I have a side question - I have the relation set up in my User model like has_many :microposts, dependent: :destroy, yet when I do these tests with the instance variable method below, I have to explicitly call delete_all on micro posts, otherwise they remain in the test db after the run (even though user gets deleted). Am I missing something obvious there or does the cascading destroy not work when user is created via Factory Girl?

UPDATE: Thanks to @Jesper I caught the reason why the after(:all) wasn't removing associated microposts. Code updated to reflect that.

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: "manyposts@example.com")
    @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
4

1 回答 1

0

Capybara 重置每个示例运行之间的会话,请参阅此答案:https ://stackoverflow.com/a/9789326/648392

很可能,您的模型已按预期设置,但测试失败,因为会话已被重置。

换句话说,您可以在before(:all)块中设置规范中所需的任何模型,但是您必须将与会话相关的东西(例如valid_session和)移动visit root_pathbefore(:each)块中。

于 2013-06-02T09:54:10.217 回答