如何构建rspec数据测试?

时间:2014-02-08 16:41:44

标签: ruby testing rspec conventions

背景

我对Ruby(和RSpec)比较陌生,我有应用程序代码发出数据对象。我希望我的规范验证Hash的结构是正确的(即它包含所有必需的键)并且数据是正确的(即输入与默认值正确合并)。这是一个简单的例子:

def returns_the_hash
  {
    :foo => "bar",
    :baz => "qux",
    :options => {
      :oof => "rab",
      :zab => "xuq",
    },
  }
end

稍后需要注意的是,整个Hash是基于输入(我的规范可用)的确定性。我必须做出的选择是如何扩展或紧凑来制作我的断言。假设在这种情况下我只对:foo:options[:zab]对感兴趣:

“显式”测试

优势:最佳意图分离

缺点:最啰嗦;引入隐藏的依赖关系

it "should be structured properly" do
  hsh = returns_the_hash
  expect(hsh).to have_key(:foo)
  expect(hsh).to have_key(:options)
  expect(hsh[:options]).to have_key(:zab)
end

it "should merge inputs with default values" do
  hsh = returns_the_hash
  # assumes that the structure is correct
  expect(hsh[:foo]).to eq("bar")
  expect(hsh[:options][:zab]).to eq("xuq")
end

“隐含”测试

优势:最简洁;易于维护

缺点:做出假设;结合结构/内容测试

it "should be well-formed" do
  hsh = returns_the_hash
  # also assumes that the structure is correct; doesn't verify it outright
  expect(hsh[:foo]).to eq("bar")
  expect(hsh[:options][:zab]).to eq("xuq")
end

问题

从覆盖的角度来看,我认为这两种策略实际上是等价的。

在rspec中是否有一个约定(或更好的,提供的机制)来测试像这样的结构和/或内容的复杂返回值?我是否应该担心将两个概念(结构和数据)结合起来并使用“隐式”测试,或者是那种糟糕的形式,我应该将这两个概念保持为“显式”示例?

或者,我是否首先攻击这个问题并且反对Ruby / Rspec自以为是的“方式”?

1 个答案:

答案 0 :(得分:0)

这取决于returns_the_hash

的意图

如果它发生变化并突然返回

{
  :lorem => "ipsum",
  :foo => "bar",
  :baz => "qux",
  :options => {
    :oof => "rab",
    :zab => "xuq",
  },
}

这是一个错误,它返回lorem / ipsum或者它可以吗?

如果这表示存在错误,那么显式隐式测试将无法捕获它,而完全测试会捕获它。

如果这种情况不是错误,那么您可以更灵活地决定其他元素对您的重要程度,以及测试是否需要较少的维护。

这取决于数据的使用方式。例如,如果散列中的所有数据最终都显示给用户,那么您的测试应该对实际返回的数据更加严格(完全测试。)