【问题标题】:RSpec test to expect only certain properties of an ActiveRecord model to changeRSpec 测试只期望 ActiveRecord 模型的某些属性发生变化
【发布时间】:2018-09-06 15:26:39
【问题描述】:

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

更新

寻找与以下等效的东西(不起作用):

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

【问题讨论】:

  • 如果你投反对票,我很想知道为什么。如果这是一个出于某种根本原因不应该编写的测试,我和其他人可能会从学习原因中受益。如果是因为问题的编写方式,请分享您的不满,以便我改进。

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


【解决方案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

【讨论】:

  • 这基本上就是我目前在测试中所做的。我想做的是确保只有这些属性发生了变化。
猜你喜欢
  • 2021-03-06
  • 2018-01-23
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多