【问题标题】:RSpec: expect array of hashes in class_double recieveRSpec:期望类双重接收中的哈希数组
【发布时间】:2015-10-20 11:08:26
【问题描述】:

我想用 RSpec 测试一个函数 my_test。该函数在 rails 4 中调用另一个类的类方法 MyHelper.func。 我在 MyHelper 类中使用 mock 来说明 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)

【问题讨论】:

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


    【解决方案1】:

    这有点棘手,因为您在使用 == 时比较两个不相等的事物

    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

    【讨论】:

    • 谢谢!这是如何使用我们自己的匹配器的一个很好的例子:)
    猜你喜欢
    • 2017-07-28
    • 2016-11-27
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2014-07-12
    • 2014-06-23
    • 1970-01-01
    相关资源
    最近更新 更多