Rails 测试函数中的数据库记录不是 saving/persisting?
Database Record not saving/persisting within a Rails test function?
我有一个 update
类型的方法,我正在尝试使用 MiniTest 和 FactoryGirl 在 Rails 中进行测试。我的问题是,虽然我可以看到更新 是 正确发生 在 更新函数中,但它似乎没有返回到测试功能正常。
这些是我们正在使用的对象,(obj
被赋予默认值 location
以开始:
location1 = create :location
location2 = create :location
obj = create :object, location: location1
然后我们调用 update
函数,它需要 id
的:
obj.update_location(obj.id, location2.id)
update
函数:
def update_location(obj_id, loc_id)
@obj = Object.find(obj_id)
@obj.location_id = loc_id
@obj.save
end
但是当回到测试文件时,我尝试 assert
更改…
assert_equal obj.location_id, location2.id
...我失败了。控制台告诉我 obj.location_id
仍然等于 location1.id
!这是为什么?
似乎 @obj.save
是 正常工作,因为我在更新函数中插入 puts @obj.inspect
并且它输出正确更新的 location_id
.
我认为这与事务回滚无关,因为这一切都发生在单个测试中。 (我的印象是事务回滚只发生在测试之间)。
总而言之,我的问题是:为什么我的更新没有持续回到 rails MiniTest test
函数?
编辑:这是整个测试:
test "update_location" do
location1 = create :location
location2 = create :location
#give the obj a starting `type`
obj = create :obj, location: location1
obj.update_location(obj.id, location2.id)
assert_equal obj.location_id, location2.id
end
2 个可能会帮助您找到答案的问题:
为什么要使用实例变量 @obj
而不是局部变量 obj
为什么你有一个特殊的方法只更新1列。 update_column 对你不起作用吗?
问题已解决,以下是我的理解:
问题在于 rails' ORM 的工作方式。原始对象 'obj' 在创建时加载了数据库中的数据……但以后对数据库的更改不会自动存储到 obj
。我原以为 obj.some_attribute
查看数据库中的记录 obj
以找到属性值——但实际上我认为属性只是在变量创建时加载到变量中,并且数据库如果我稍后调用 obj.some_attribute
,则无法访问。
通常,当通过变量本身完成更新时,Rails 知道为您更新变量。所以当你写 obj.some_attribute = 5
,然后再写 obj.some_attribute
时,Rails 知道值应该是 5。但是 Rails 魔法在这种情况下不会发生因为它没有通过变量更新记录。
所以需要做的只是reload
数据库中的对象。
所以 assert_equal obj.reload.location_id, location2.id
有效!
我有一个 update
类型的方法,我正在尝试使用 MiniTest 和 FactoryGirl 在 Rails 中进行测试。我的问题是,虽然我可以看到更新 是 正确发生 在 更新函数中,但它似乎没有返回到测试功能正常。
这些是我们正在使用的对象,(obj
被赋予默认值 location
以开始:
location1 = create :location
location2 = create :location
obj = create :object, location: location1
然后我们调用 update
函数,它需要 id
的:
obj.update_location(obj.id, location2.id)
update
函数:
def update_location(obj_id, loc_id)
@obj = Object.find(obj_id)
@obj.location_id = loc_id
@obj.save
end
但是当回到测试文件时,我尝试 assert
更改…
assert_equal obj.location_id, location2.id
...我失败了。控制台告诉我 obj.location_id
仍然等于 location1.id
!这是为什么?
似乎 @obj.save
是 正常工作,因为我在更新函数中插入 puts @obj.inspect
并且它输出正确更新的 location_id
.
我认为这与事务回滚无关,因为这一切都发生在单个测试中。 (我的印象是事务回滚只发生在测试之间)。
总而言之,我的问题是:为什么我的更新没有持续回到 rails MiniTest test
函数?
编辑:这是整个测试:
test "update_location" do
location1 = create :location
location2 = create :location
#give the obj a starting `type`
obj = create :obj, location: location1
obj.update_location(obj.id, location2.id)
assert_equal obj.location_id, location2.id
end
2 个可能会帮助您找到答案的问题:
为什么要使用实例变量
@obj
而不是局部变量obj
为什么你有一个特殊的方法只更新1列。 update_column 对你不起作用吗?
问题已解决,以下是我的理解:
问题在于 rails' ORM 的工作方式。原始对象 'obj' 在创建时加载了数据库中的数据……但以后对数据库的更改不会自动存储到 obj
。我原以为 obj.some_attribute
查看数据库中的记录 obj
以找到属性值——但实际上我认为属性只是在变量创建时加载到变量中,并且数据库如果我稍后调用 obj.some_attribute
,则无法访问。
通常,当通过变量本身完成更新时,Rails 知道为您更新变量。所以当你写 obj.some_attribute = 5
,然后再写 obj.some_attribute
时,Rails 知道值应该是 5。但是 Rails 魔法在这种情况下不会发生因为它没有通过变量更新记录。
所以需要做的只是reload
数据库中的对象。
所以 assert_equal obj.reload.location_id, location2.id
有效!