我试图找出功能测试中发生的事情与我的开发环境中发生的事情之间的不一致。我有一个自定义验证方法unique_entry
,它本质上是validates_uniqueness_of
的专用版本。它看起来像这样:
def unique_entry
matched_entry = Entry.first(:conditions => ['LOWER(field_one) = LOWER(?) AND LOWER(field_two) = LOWER(?)', self.field_one, self.field_two])
errors.add_to_base('Duplicate detected') if matched_entry && (matched_entry.id != self.id)
end
控制器中的更新操作非常基本:
def update
if @entry.update_attributes(params[:entry])
flash.now[:success] = 'Success'
render :action => 'show'
else
flash.now[:error] = 'Error'
render :action => 'edit'
end
end
当我创建新记录时,这很好用。但是,当我更新记录时,我会遇到不一致的行为。如果我在开发环境中从浏览器测试它,它会正确地呈现edit
操作并显示错误消息,但在我的功能测试中,它接受更新成功。这是测试:
test "should not update entry and should render edit view if invalid update" do
put :update, { :id => 1, :field_one => 'new_value', :field_two => 'new_value' } # 'new values' are the same as another existing record to trigger the duplication check
assert_template :edit
assert_not_nil flash[:error]
end
我查看了测试日志,发现值unique_entry
正在使用的是记录的原始值,而不是它应该尝试更新的值。也就是说,unique_entry
的第一行生成如下的SQL查询:
SELECT * FROM "entries" WHERE (LOWER(field_one) = LOWER('original_value_of_field_one') AND LOWER(field_two) = LOWER('original_value_of_field_two')) LIMIT 1
我在这里缺少什么?为什么我的验证似乎只针对原始记录运行而不是仅在测试环境中运行新值?
答案 0 :(得分:2)
在您的测试中,不应该有:entry
的引用,因为这是您在控制器params[:entry]
中寻找的内容?