Rails: невозможно инициализировать has_many: через ассоциацию изнутри модульного теста с использованием имени класса модели - PullRequest
0 голосов
/ 02 июля 2010

Я изо всех сил пытался понять, почему я могу легко использовать seed.rb для создания новых пользователей и их ассоциаций по умолчанию, но при запуске отдельных юнит-тестов возникают ошибки.Я пытался обойти вызов «Роль», так как это вызывает ошибки в модульном тесте.Я относительно новичок в модульном тестировании, но использую Rails уже несколько лет.Хотя все это работает, я хочу, чтобы тесты прошли без ошибок.

ruby ​​1.8.7
gem 1.3.7
Rails 2.3.8

app / models / user.rb

class User < ActiveRecord::Base

  has_many :user_roles, :dependent => :destroy              
  has_many :roles, :through => :user_roles, :uniq => true, :order => :id

  has_one  :contact, :as => :owner, :dependent => :destroy

  attr_accessor   :password

  before_save :build_default_associations, :if => :new_record?

def build_default_associations
  update_encrypted_password
  build_contact(:email => name) 
  user_roles.build(:role_id => Role.find_by_name("subscriber")id )
  #
  # the below also works in seeds.rb but causes a different error
  # roles << Role.find_by_name("subscriber") 
  # ActiveRecord::AssociationTypeMismatch: Role(#2162845660) expected, got NilClass(#2148404100)
  # 
end

db / seed.rb

# This places the default Role in the db
Role.create({:name => "subscriber", :description => "This will be the default"})
# associations initialize and save with 
User.create(:name => "valid@email.com", :password => "abcde")  

test / unit / user_test.rb

# assertions DO NOT fail, but raise the error below! 
def test_should_create_user_and_add_default_role
  user = User.create(:name => 'ok@good.org', :password => 'abcde') #minimum length password
  assert !user.new_record?
  assert user.roles.exists?("subscriber")
end

ruby ​​test / unit / user_test.rb

1) Ошибка:
test_should_create_user_and_add_default_role (UserTest):
RuntimeError: Вызывается id для nil, который по ошибке будет равен 4 - если вы действительно хотите идентификатор nil, используйте object_id
app / models / user.rb:31: в 'build_default_associations'
unit / user_test.rb: 31: в `test_should_create_user_and_add_default_role '

Есть мысли?Кажется, я не могу найти лучшие практики, которые запрещают это ...

Ответы [ 2 ]

0 голосов
/ 02 июля 2010

Мне нужно было предотвратить загрузку и уничтожение приборов по умолчанию для моих тестовых данных, которые загружаются из db / seed.rb путем редактирования test / test_helper.rb

Тем не менее из ошибок не было ясно, что мойтестовые данные были сфабрикованы, но как только я написал тесты, которые подтвердили, что мои роли по умолчанию были (не) на месте ....

test / unit / user_test.rb

def test_users_exist
  assert_equal User.count, 8   # test was expecting 2, b/c of default yml fixtures!
end

test /test_helper.rb

# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
# fixtures :all  <--- for now load none, since testing data from db/seeds.rb

test / unit / user_test.rb

# No error, No fail 
def test_should_create_user_and_find_default_role
  user = User.create(:name => 'ok@good.org', :password => 'abcde')
  assert user.roles.exists?(:name => "subscriber") 
end
0 голосов
/ 02 июля 2010

Как выглядит Role.default?Похоже, что он возвращает ноль в тестовой среде, поэтому я предполагаю, что вы пропустили запись роли «по умолчанию» в тестовой БД.

По умолчанию каждый тест выполняется внутри транзакции, а затем откатываетсякак только он закончится, вам нужно будет явно установить любое состояние БД, которое требуется вашим тестам.Вы могли бы использовать, возможно, использовать приборы или создать его в блоке установки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...