我正在将我的应用程序从Rails 4.0升级到4.1(在前往4.2的路上)并且让这样的测试失败:
describe "#restore_disabled_account" do
let(:username) { 'username' }
let(:email) { 'email@domain.com' }
let(:m3_user) { create(:user, username: username,
email: email,
archived: false,
propagate_in_test_mode: true) }
let(:m2_user) { Maestro2::User.where(UserID: m3_user.id).first }
before do
m3_user.disable_account
end
it "unarchives the account" do
m3_user.restore_disabled_account
m3_user.reload
expect(m3_user.archived).to be_falsey
end
end
我已经验证数据库包含在此测试开始时具有预期属性的记录。在调试测试时,我在重载语句之前停止,我看到db记录已按预期更新(存档为false,其他属性按预期更新)。我还可以看到m3_user对象已使用相同的属性进行更新。当我前进运行重新加载步骤并查询数据库时,我可以看到记录已恢复到其原始状态,内存中的对象也是如此。然后测试失败,因为m3_user.archived为真。
有人可以告诉我为什么吗?我的套件中的所有测试都在开始升级之前通过。该应用程序目前使用的是Ruby 2.2.4,Rails 4.1.16,rspec 3.5.3和rspec-rails 3.5.2
作为参考,下面是两个User类方法调用:
def disable_account
self.update_attributes(username: "disabled_#{id}_#{username}",
email: "disabled_#{id}_#{email}",
archived: true)
end
def restore_disabled_account
self.update_attributes(username: username.gsub(/^disabled_#{id}_/, ''),
email: email.gsub(/^disabled_#{id}_/, ''),
archived: false)
end
答案 0 :(得分:0)
简短回答:事实证明,ActiveRecord 4.1更改了reload
方法以调用名为reset_changes
的新私有方法。我的用户类也有一个reset_changes
方法,因此我的方法覆盖了应该调用的内容。
答案很长:我看到的越多,我就越怀疑我的用户模型独有的东西。使用reload
的其他测试按预期执行。然后我在User中遇到了reset_changes
方法。看到它做了什么(用以前的值更新db记录)后,我将一个puts语句放入其中,以便我看看它是否被调用。一旦确认,我就抛弃了调用者回溯,它指向https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/attribute_methods/dirty.rb#L37
我已将用户模型方法更改为undo_changes
,我的规格为绿色。