数据库记录没有保存/保留在 Rails 测试功能中?

Posted

技术标签:

【中文标题】数据库记录没有保存/保留在 Rails 测试功能中?【英文标题】:Database Record not saving/persisting within a Rails test function? 【发布时间】:2015-08-30 03:17:43 【问题描述】:

我有一个update-type 方法,我正在尝试使用 MiniTest 和 FactoryGirl 在 Rails 中进行测试。我的问题是,虽然我可以看到更新 is 正确地发生在更新函数内,但它似乎并没有正确地延续到测试函数中。

这些是我们正在使用的对象,(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

【问题讨论】:

我认为我们需要先了解整个测试周期,然后才能以任何合理的方式考虑它。我也会尝试save! 以避免饮食异常。 我在文件中添加了整个且唯一的测试函数。我只使用 rake test test/models/obj_test.rb 运行该文件 (@DaveNewton-Tried save!,没有帮助...) 【参考方案1】:

问题已解决,以下是我的理解:

问题在于 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 有效!

【讨论】:

【参考方案2】:

2 个可能帮助您找到答案的问题:

    你为什么使用实例变量@obj而不是局部变量obj

    为什么你有一个特殊的方法来更新 1 列。 update_column 不适合你吗?

【讨论】:

寻求帮助!以下是您 Q 的答案……1-不确定为什么要使用它,但请注意它位于与测试不同的文件中(位于 app/models/objects.rb 中)。 2-它确实是一个更大的方法的一部分,可以做更多的事情,我只是简化了它……:P (我确实尝试从 @obj 切换到 obj,但无济于事。)

以上是关于数据库记录没有保存/保留在 Rails 测试功能中?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Xcode 7 保留来自 UI 测试目标的日志记录输出?

Rails:2单击一个提交按钮在两个数据库中插入记录(将一个控制器的记录保存在另一个控制器中)

Rails:使远程代理持久保留活动记录

Rails 4+ 最佳实践:删除父项同时保留子项

markdown 当活动记录子对象在Rails中自动保存时

Rails 5:在连接表记录上保存记录时的 STI 空键