RSpec测试只能期望ActiveRecord模型的某些属性发生变化

时间:2018-03-28 04:29:34

标签: ruby-on-rails rspec rspec-rails

我正在成功测试ActiveRecord模型的某些属性是否已更新。我还想测试那些属性是否已经改变。我希望我可以使用模型的.changes.previous_changes方法来验证我希望更改的属性是唯一被更改的属性。

更新

寻找与以下相同的东西(不起作用):

it "only changes specific properties" do
  model.do_change
  expect(model.changed - ["name", "age", "address"]).to eq([])
end

1 个答案:

答案 0 :(得分:1)

尝试这样的事情

expect { model.method_that_changes_attributes }
  .to change(model, :attribute_one).from(nil).to(1)
  .and change(model, :attribute_two)

如果更改不是属性,而是您可能需要重新加载模型的关系:

# Assuming that model has_one :foo
expect { model.method_that_changes_relation }
  .to change { model.reload.foo.id }.from(1).to(5)

编辑:

在OP评论中做出一些澄清之后:

你可以这样做

# Assuming, that :foo and :bar can be changed, and rest can not

(described_class.attribute_names - %w[foo bar]).each |attribute|
  specify "does not change #{attribute}" do
    expect { model.method_that_changes_attributes }
      .not_to change(model, attribute.to_sym)
    end
  end
end

这基本上就是你所需要的。

此解决方案有一个问题:它会为每个属性调用method_that_changes_attributes,这可能效率低下。如果是这种情况 - 您可能想要创建自己的接受一系列方法的匹配器。开始here