Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

ruby on rails - config.cache_classes = false messing up rspec tests?

I'm following the Ruby on Rails Tutorial by Michael Hartl (railstutorial.org).

At some point I got tired of tests failing just bescause the tests used old cached versions of classes, so I turned off config.cache_classes in the test environment. That fixed the issue and everything went good for some time.

Until I tried implementing the Integration tests in Chapter 8.4.3. At this point the data entered into the database with

it "should make a new user" do
    lambda do
      visit signup_path
      fill_in "Name",         :with => "Example User"
      fill_in "Email",        :with => "user@example.com"
      fill_in "Password",     :with => "foobar"
      fill_in "Confirmation", :with => "foobar"
      click_button
      response.should have_selector("div.flash.success",
                                    :content => "Welcome")
      response.should render_template('users/show')
    end.should change(User, :count).by(1)
  end

would remain in the Database after each test, so only the first time this test ran it would work, after that it always fails until i manually empty the database. Apart from that it worked. But now in chapter 9, again the integration test fails:

describe "when signed in" do

before(:each) do
  @user = Factory(:user)
  visit signin_path
  fill_in :email,    :with => @user.email
  fill_in :password, :with => @user.password
  click_button
end

it "should have a signout link" do
  visit root_path
  response.should have_selector("a", :href => signout_path,
                                     :content => "Sign out")
end

This time it just doesn't work, the user is not getting logged in and the resulting page has no sign out link, just the normal sign in link. When testing this in a webbrowser it works fine.

It took me hours and days of searching the internet and testing different stuff and finally I found the solution: Turning config.cache_classes back on. Now it works flawlessly.

So can anyone explain to me why config.cache_classes makes the tests fail? And how can I turn off caching without messing up my tests?

Thanks in Advance,

Best regards, Tobias

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you make a Capybara call, it uses rack-test to emulate a call to the rails app. Every time a call is completed, it reloads all rails classes. What this means is that the @user object you created before you called 'visit signin_path' gets nil'd out because all ActiveRecord objects have been reloaded.

When you set cache-classes to true, it tells Rack not to reload the ActiveRecord objects on every request, so your tests pass again.

I believe that if you want the test you wrote above to pass without turning on cache-classes, you should move the '@user = Factory(:user)' line below the 'visit signin_path' line.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...