RSpec:期望在class_double中接收哈希数组

时间:2015-10-20 11:08:27

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

我想用RSpec测试一个函数my_test。该函数在rails 4中调用另一个类的类方法MyHelper.func。 我使用mock来说明类MyHelper中的func,我希望将func接收的参数与一些const值匹配。

我用过

expect(<double>).to receive(func).with(arguments)

但是其中一个const参数是一个包含2个以上项的哈希。当我测试我的 函数,RSpec抛出错误:

received :func with unexpected arguments.
expected: [{"1"=>33.33},{"2"=>33.33},{"3"=>33.33}]
got: [{"2"=>33.33},{"1"=>33.33},{"3"=>33.33}]

有没有办法在两个阵列之间进行匹配? 代码:

my_hash = [{"1"=>33.33},{"2"=>33.33},{"3"=>33.33}]
notifier = class_double("MyHelper").
              as_stubbed_const(:transfer_nested_constant => true)
 expect(notifier).to   receive(:func).with(my_hash)

1 个答案:

答案 0 :(得分:0)

这有点棘手,因为你在使用==时比较两个不相等的东西

let(:expected)  { [{"1"=>33.33},{"2"=>33.33},{"3"=>33.33}] }
let(:actual)    { [{"2"=>33.33},{"1"=>33.33},{"3"=>33.33}] }

expect(actual).to eq(expected) # fails

但是,您可以定义自定义匹配器并使用它来比较参数:

RSpec::Matchers.define :sorted_array_match do |expected|
  match do |actual|
    expected_hash = expected.inject({}) {|m,(k,v)| m.merge!(k=>v)}
    actual_hash   = actual.inject({}) {|m,(k,v)| m.merge!(k=>v)}
    actual_hash   == expected_hash
  end
end

it "should work" do
  expect(notifier).to receive(:func).with(sorted_array_match(expected))
  notifier.func(actual)
end

请注意,这会将数组参数转换为散列,因此它假定参数是包含具有不同键的散列的数组。您可能需要更改它以适合实际数据。

RSpec docs中的更多信息。