Ruby on rails RSpec,预期将使用多个值进行更改

Ruby on rails RSpec,预期将使用多个值进行更改,ruby-on-rails,rspec,Ruby On Rails,Rspec,可能重复: 这允许我检查“配方”模型是否还有一个条目,但我还想检查“配料”模型是否还有一个条目。expect块只能执行一次,因为表单已经提交 我知道我可以制作另一个“it”块,但我觉得必须有一种更干燥的方法。您可以将所有这些抽象为一个helper方法 def test_creation_of(model) it "should create a new #{model}" do expect { click_button submit }.to change(model.const

可能重复:

这允许我检查“配方”模型是否还有一个条目,但我还想检查“配料”模型是否还有一个条目。expect块只能执行一次,因为表单已经提交


我知道我可以制作另一个“it”块,但我觉得必须有一种更干燥的方法。

您可以将所有这些抽象为一个helper方法

def test_creation_of(model)
  it "should create a new #{model}" do
    expect { click_button submit }.to change(model.constantize, :count).by(1)
  end
end
但我只会建议,如果你会这样做,为许多型号。否则它只会使代码更难阅读。如果这样做,最好将其放入等级库帮助器中

此外,根据测试中的其他先例,您可以传递一个Const对象而不是字符串(正如我在上面的示例中所使用的)

然后


我建议通过重新定义测试主题(并用于娱乐)使其干涸:

更新:虽然它看起来不那么干燥,但这些天我可能仍然会继续使用
expect
语法,因为它是而且我通常会远离
应该
,但可能会对规范的可读性做一些小的更改:

describe "recipe creation" do
  let(:creating_a_recipe) { -> { click_button submit } }

  it "changes the Recipe count" do
    expect(creating_a_recipe).to change(Recipe, :count).by(1)
  end

  it "changes the Ingredient count" do
    expect(creating_a_recipe).to change(Ingredient, :count).by(1)
  end
end
注意:您可以在中看到
expect
使用了花括号。当然,这是正确的,但是标准括号在本例中起作用的原因是,更改可变状态的代码(包含在
创建配方
中)位于lambda中,当作为参数传递到
expect
时会调用该lambda


无论如何,在这种情况下,
expect(creating_a_recipe)
expect{creating_a_recipe}
都可以成功地使用,并且无论使用哪一种,都取决于个人的喜好。

这个问题对于codereview.stackexchangefor未来:此代码有效。在这种情况下,否决票通常是不合适的-您应该用不同意的方式进行评论(或者说明为什么这段代码不能解决问题)。这是测试模型创建的一个很好的抽象,但是OP询问如何通过单击来测试两个模型的创建。不过你说得对,写评论比简单地投否决票更能促进一个更好的社区。我的错。有趣的是,因为已经两天了,所以在你更新答案之前,我不会收回我的反对票。谢谢!顺便说一句,这仍然会单击“提交”两次,因此可能不起作用(例如,如果在单击“提交”后页面重定向,或者表单不再有效)。问题现在已关闭,但为了方便起见,
…}。将{[val1,val2]}.from([old_val1,old_val2])
更改为{[val1,val2]}.from可以很好地工作。请注意,对于发生的任何事情,都需要实际调用lambda。我使用方括号来实现这一点,即
创建一个配方[]
expect
如果传入一个lamba,它将调用一个lamba。
it "should create a new Recipe" do
  test_creation_of( 'Recipe' )
  test_creation_of( 'Ingredient' )
end
describe "recipe creation" do
  subject { -> { click_button submit } }
  it { should change(Recipe, :count).by(1) }
  it { should change(Ingredient, :count).by(1) }
end
describe "recipe creation" do
  let(:creating_a_recipe) { -> { click_button submit } }

  it "changes the Recipe count" do
    expect(creating_a_recipe).to change(Recipe, :count).by(1)
  end

  it "changes the Ingredient count" do
    expect(creating_a_recipe).to change(Ingredient, :count).by(1)
  end
end