2011-09-17 32 views
3

我正在使用RSpec测试我的Rails应用程序,但后来遇到了问题。我想要一个一致的数据库,因此我强加了一些约束,某些列不能为空。Ruby on 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模型只namecomment访问

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列表的详细属性,这可能会成为一个大量的工作。或者,如果你有更好的设计模式,请让我知道

谢谢

+0

如果您使用'create!',该怎么办? – apneadiving

回答

1

只需使用:

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

我发现'@ comment.answers <<'方法返回一个数组,因此这个解决方案适用于我: @ comment.answers <<(@answer = Factory.build(:comment)) 再次感谢您的帮助 – k13n

0

我在测试过程中基本上使用了this的变体(以及其他一些调整)。

(但法比奥的答案是清洁 - 这是的东西工厂都是为一体,使事情 - 不仅仅是属性:)

2

我碰到这个问题跑,而寻找解决的办法,以同样的持有人问题。我知道这是很老了,但是这是非常值得我通过代码挖出,并决定要解决的问题是这样的:

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

这或许能派上用场别人谁在这里卷起。