Ruby on rails RSpec测试仅期望ActiveRecord模型的某些属性发生更改

Ruby on rails RSpec测试仅期望ActiveRecord模型的某些属性发生更改,ruby-on-rails,rspec,rspec-rails,Ruby On Rails,Rspec,Rspec Rails,我正在成功地测试是否更新了ActiveRecord模型的某些属性。我还想测试只有那些属性发生了变化。我希望我可以连接到模型的。更改或。以前的更改方法验证我希望更改的属性是唯一被更改的 更新 正在寻找与以下内容等效的内容(不起作用): 试试这样的 expect { model.method_that_changes_attributes } .to change(model, :attribute_one).from(nil).to(1) .and change(model, :attri

我正在成功地测试是否更新了ActiveRecord模型的某些属性。我还想测试只有那些属性发生了变化。我希望我可以连接到模型的
。更改
。以前的更改
方法验证我希望更改的属性是唯一被更改的

更新

正在寻找与以下内容等效的内容(不起作用):


试试这样的

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
这基本上就是你需要的


但是这个解决方案有一个问题:它将调用
方法\u来更改每个属性的属性
,这可能是低效的。如果是这样的话,您可能希望创建自己的匹配器,它接受一个方法数组。开始

如果你来投票,我想知道为什么。如果这是一个出于某种根本原因而不应该编写的测试,我和其他人可能会从了解原因中受益。如果是因为问题的写作方式,那么请分享你的不满,这样我可以改进它。这基本上就是我目前在测试中所做的。我想做的是确保只有那些属性发生了更改。
# 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