Ruby on Rails позволяет массовое назначение для теста RSpec - PullRequest
3 голосов
/ 17 сентября 2011

Я тестирую свое Rails-приложение с RSpec, но потом столкнулся с проблемой. Мне нужна согласованная база данных, поэтому я наложил ограничение на то, что некоторые столбцы не могут быть пустыми.

У меня есть модель комментариев, и комментарий может быть ответом на другой комментарий. Более комментарий имеет IP-адрес, который не должен быть нулевым. Это миграция:

create_table :comments do |t|
  t.string :name, :limit => 20, :null => false
  t.string :comment, :limit => 8192, :null => false
  t.string :ip, :null => false
  t.integer :answer_to_comment_id
end

Затем я создал Comment модель с только name и comment доступными

class Comment < ActiveRecord::Base
  attr_accessible :name, :comment

  belongs_to :answer_to, :class_name => "Comment", 
                         :foreign_key => "answer_to_comment_id"

  has_many :answers, :class_name => "Comment", 
                     :foreign_key => "answer_to_comment_id", 
                     :dependent => :destroy
end

Мой factories.rb выглядит так:

Factory.define :comment do |comment|
  comment.name    "test"
  comment.comment "test"  
  comment.ip      "0.0.0.0"
end

Теперь у меня есть следующая проблема в тесте RSpec comment_spec.rb

describe "some test" do
  before(:each) do
    @answer = @comment.answers.create(Factory.attributes_for(:comment))
  end
end

Это не удастся, поскольку :ip отсутствует в списке attr_accessible и, следовательно, ActiveRecord не может создать запись в базе данных. Я мог бы добавить :ip в список, но это может вызвать некоторые проблемы с безопасностью из-за массового назначения. Или я мог бы добавить :ip вручную, но это могло бы стать большой работой, если бы было больше атрибутов, таких как ip

Так что я ищу возможность обойти список attr_accessible. Или, если у вас есть лучший дизайн шаблона, пожалуйста, дайте мне знать

Спасибо

Ответы [ 3 ]

3 голосов
/ 10 декабря 2012

Я наткнулся на этот вопрос, когда искал решение той же проблемы. Я знаю, что он очень старый, но для чего он стоит, я покопался в коде и решил решить проблему следующим образом:

before :each do
  ActiveModel::MassAssignmentSecurity::WhiteList.any_instance.stub(:deny?).and_return(false)
end

Возможно, это пригодится кому-то еще, кто окажется здесь.

1 голос
/ 17 сентября 2011

Просто используйте:

describe "some test" do
  before(:each) do
    @answer = @comment.answers << Factory(:comment)
  end
end

или если вам нужно более одного комментария, скажите n

describe "some test" do
  before(:each) do
    @answer = @comment.answers = FactoryGirl.create_list(:comment, n)
  end
end
0 голосов
/ 17 сентября 2011

Я в основном использую вариант this (вместе с несколькими другими настройками) во время тестирования.

(Но ответ Фабио чище - это одна из вещей, для которой фабрики делают, а не просто держатель атрибутов:)

...