2012-07-11 55 views
1

我有这样的错误在我的两个测试:名为id的零,这将误在控制器测试4

test "should create question" do 
    assert_difference('Question.count') do 
    post :create, question: { question: 'apple', answer: "good", holder_id: 2} 
    end 
end 

test "should not create question" do 
    invalid_answer = "a" * 145 
    assert_difference('Question.count',0) do 
    post :create, question: { answer: invalid_answer } 
    end 
    assert_template 'new' 
end 

我创建行动

#create action 
def create 
    @question = Question.new(params[:question]) 
    @holder = Holder.find_by_id(@question.holder.id) 
    if @question.save 
    flash[:success] = "Question Saved" 
     redirect_to holder_path(@question.holder_id) 
    else 
     render 'new' 
    end 
end 

堆栈跟踪显示它是创造两条线。但是,我怎么得到Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id错误?

我需要先创建一个对象,然后将其传递给创建后?

+1

什么是你创建的行动看起来像在控制器?某个地方你正在对尚未创建的东西调用'.id'。也许你做了''question.type = QuestionType.normal.id'这样的事情 - 也就是说,你使用“种子”数据,而且它没有加载?如果您发布创建操作,它会帮助我们。 – MrDanA 2012-07-11 16:09:27

+1

它是:'@holder = Holder.find_by_id(@ question.holder ***。id ***)'。稍后,您使用@ question.holder_id,它不引发异常。但是,您似乎希望避免创建没有持有者的问题,例如通过验证。 Rep to @MrDanA - 你应该把它作为答案。 – emrass 2012-07-11 16:29:52

回答

1
@question = Question.new(params[:question]) 
    @holder = Holder.find_by_id(@question.holder.id) 

是的你是对的,你需要在运行这个测试之前创建Holder实例。

但是你为什么要创建所有的ivars,你需要新的吗?

如果没有它似乎可以把代码dryed高达

def create 
    question = Question.new(params[:question]) 
    if question.save 
    flash[:success] = "Question Saved" 
     redirect_to holder_path(question.holder) # but some checks are in order here, no? 
    else 
     render 'new' 
    end 
end 

HTH 罗伯特