关于重复预期的Rspec指导

时间:2014-09-03 11:40:41

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

我有一个这样的测试用例。

subject(:report) { @report.data }
it { expect(report[0][:id]).to eq(@c1.id) }
it { expect(report[1][:id]).to eq(@c2.id) }
it { expect(report[2][:id]).to eq(@c3.id) }
it { expect(report[0][:title]).to eq("Announcement3") }
it { expect(report[1][:title]).to eq("Announcement2") }
it { expect(report[2][:title]).to eq("Announcement1") }

我觉得这不是一种有效的方法。

还有其他方法可以提高效率吗?所以它看起来像一个线条件。

3 个答案:

答案 0 :(得分:3)

测试行为,非构成

始终测试行为,而不是合成。你应该在这里测试的是行为给出一些固定输入,报告每次都会生成相同的固定输出。你不是那样做的;您可以反省单个报告元素,这些元素与组合有关。

相反,请考虑使用fixture或FactoryGirl(甚至只是一个设置块)来定义固定输入,然后检查:

it 'creates valid report data' do
  expect(@report.data).to eq @sample.data
end

更多关于行为

如果报告的每个元素来自不同的方法,您应该分别测试每个方法的行为,而不是分解最终报告。这是使您的测试更清晰,更有意义的另一种方法,并解决了#34;单位"在单元测试中。

答案 1 :(得分:1)

我宁愿写这样的东西:

it { expect(report[0]).to include(id: @c1.id, title: "Announcement3") }
it { expect(report[1]).to include(id: @c2.id, title: "Announcement2") }
it { expect(report[2]).to include(id: @c3.id, title: "Announcement1") }

它没有深入报告结构,对我来说看起来更具可读性。

答案 2 :(得分:0)

您可以将报告映射到您关注的密钥并对此做出预期:

expect(report.map { |h| h[:title] }).to eq [array, of, values]

您可以使用include检查每个报告成员的密钥:

expect(report[0]).to include id: @c1.id, title: "Announcement3"

您可以构建“预期”对象并测试相等性:

expected = [{ id: @c1.id, title: "Announcement3" }, ...]
expect(report).to eq expected