问题描述
我正在使用 Minitest 并有一个这样的控制器:
def update
authorize @flag
respond_to do |format|
if @flag.update(flag_params)
format.html { redirect_to flags_path,success: "#{@flag.name} was successfully updated." }
format.js
else
format.html { render :edit }
# format.js
end
end
end
我有一个 JS 远程选择,它触发表单提交,然后返回数据表更新。在开发等方面工作正常。我注释掉了 else 的格式,以便在更新失败时强制出现 no format
错误。
这是我的测试:
test "should assign flag" do
assert_changes 'flags(:one).assigned_id' do
patch flag_url flags(:one),format: :js,params: { flag: { assigned_id: users(:operator).id } }
end
end
asssigned_id
的 flags(:one)
为零,所有补丁都会将该列更新为来自用户设备的 id。然而我的测试失败了:
FAIL FlagsControllerTest#test_should_assign_flag (44.56s)
"flags(:one).assigned_id" didn't change
test/controllers/flags_controller_test.rb:38:in `block in <class:FlagsControllerTest>'
然而这通过了:
patch flag_url @flag,params: { flag: { assigned_id: users(:operator).id } }
assert_response :success
这也失败了:
assert flags(:one).assigned_id_changed?
我已经仔细检查了我的测试/代码,并且认为我在这里没有遗漏任何东西。
我是否遗漏了一些明显的东西,或者我没有正确应用断言?
更新的答案信息
这是我更新的模型测试:
require 'test_helper'
class FlagTest < ActiveSupport::TestCase
fixtures :flags
let(:flag_one) { flags(:one) }
end
和控制器测试:
require 'test_helper'
class FlagsControllerTest < Actiondispatch::IntegrationTest
test "should assign flag" do
assert_changes 'flag_one.assigned_id' do
patch flag_url flag_one,params: { flag: { assigned_id: users(:operator).id } }
end
end
解决方法
认为问题在于,当您像这样直接在代码中调用夹具时...
assert_changes 'flags(:one).assigned_id' do
patch flag_url flags(:one),format: :js,params: { flag: { assigned_id: users(:operator).id } }
end
..测试从夹具重新加载实例,当然它没有改变。我从来没有用夹具参考内联编写过测试。我通常做的是使用夹具中的值设置一个 let...
class FlagTest < ActiveSupport::TestCase
fixtures :flags
let(:a_flag){flags(:one)}
然后在我的测试中使用它。
test "should assign flag" do
assert_changes 'a_flag.assigned_id' do
patch flag_url a_flag,params: { flag: { assigned_id: users(:operator).id } }
end
end
如果您进行了多次测试,可以节省一些输入,并且应该可以解决您的问题。