简体   繁体   中英

Ruby on Rails 2.3.8: Testing: How do I set up an instance variable to use throughout my tests?

Lets say I have some data that remanis the same throughout all of my tests, for forever and eternity. I create this data in setup . I store the data to @instance_var . But when I call @instance_var.attribute in any test, I get the following error:

RuntimeError: Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

I know my instance variable isn't null, cause after it is set, I can do a puts @instance_var.inspect on it...

Any ideas?

EDIT:

 setup do
    user = Factory(:user)
    account = Factory(:account)    

    set_user(user)
    set_account(account)


    puts "||||||||||||||||||||||||||||||||||||||||||||||" #this proves that the instance vars are not null
    puts "| object_test.rb                            |"
    puts "|      #{@user.name}                   "
    puts "|      #{@account.name}                "
    puts "||||||||||||||||||||||||||||||||||||||||||||||"
  end

A failing test (with the error above)

test "for detection of first content with multiple contents" do
      object = Factory(:object, :user_id => @user.id, :account_id => @account.id)
   ... #the rest of this test isn't important, as it is the above line, on @user, where the nil.id error occers

in test_helper.rb

def set_user(user)
  @user = user
end

def set_account(account)
  @account = account
end

I don't really think I need these two methods, as when I define the @instance variable in setup, I get teh same result

in test_helper.rb there are some constants set fore ActiveSupport::TestCase:

  self.use_transactional_fixtures = true

  self.use_instantiated_fixtures  = false

  fixtures :all

disabling these did nothing. =(

Have you tried

setup do
  @user = Factory(:user)
  @account = Factory(:account)
end

Normally, if you set the instance variables in the setup block, they should be available to all your tests. (You might be having an issue with scopes.)

My solution was to make a shared class, shared_test.rb

require 'test_helper'

class SharedTest
  def self.initialize_testing_data
    self.reset_the_database

    self.set_up_user_and_account
    # make sure our user and account got created 
    puts "|||||||||||||||||||||||||||||||||||||||||||||"
    puts "| The user and account "
    puts "| we'll be testing with:"
    puts "|             #{@user.name}"
    puts "|             #{@user.account.name}"
    puts "|||||||||||||||||||||||||||||||||||||||||||||"
  end

  def self.reset_the_database
    #clear the database and reset it
    call_rake("db:test:prepare")
    call_rake("db:bootstrap RAILS_ENV=test")
  end

  def self.set_up_user_and_account
    #set up our user for doing all our tests (this person is very busy)  
    @user = Factory(:user)
    @account = Factory(:account)    
    @user.account = @account
    @user.save
  end
end

so then at the top of every test file that needs user and account to stay the same between all the tests, you just do

require 'shared_test.rb'

and methods are called like

SharedTest.initialize_testing_data 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM