【问题标题】:Test the size of array received is correct测试接收到的数组大小是否正确
【发布时间】:2021-03-06 04:14:09
【问题描述】:

我想测试一个类的函数是否被特定长度的数组调用。

下面的示例我想验证函数 s3upload 是否使用数组大小​​为 2 的数组参数调用。

  • ATest_spec.rb 是测试类。 AwsUploader.s3upload 是从 letsUpload 调用的
Project/lib/First/version.rb
  module Documentz
    class AwsUploader
      def s3upload(event_id:nil, docs: nil)
        puts("uploded")
      end
    end
  end
Project/lib/First.rb
  module Exporter
    class AnExporter
      def letsUpload
        Documentz::Uploader::AwsUploader.new.s3upload( docs :[1,2])
      end
    end
  end
ATest_spec.rb
  it 'helps in mocking a class' do
    exp=Exporter::AnExporter.new
    exp.letsUpLoad
    allow_any_instance_of(Documentz::Uploader::AwsUploader).to receive(:s3upload).with( {:docs=>[1,2]})
    ## how to check if the array size (:docs)==2
  end

正如您在ATest_spec.rb 中注意到的那样,我可以测试参数是否为 [1,2] 但我实际上想验证数组的大小(接收到的参数)实际上是 2。

你能建议怎么做吗?

【问题讨论】:

    标签: ruby-on-rails ruby rspec


    【解决方案1】:

    我将使用new 方法而不是allow_any_instance_of 存根,并返回一个instance_double,我在它上面监视预期的方法调用。为确保参数具有特定结构,请使用可以根据需要复杂的自定义匹配器,例如:

    RSpec::Matchers.define :expected_data_structure do
      match { |actual| actual.is_a?(Hash)         &&
                       actual[:docs].is_a?(Array) && 
                       actual[:docs].size == 2    &&
                       actual[:docs].all?(Integer) 
      }
    end
    
    subject(:exporter) { Exporter::AnExporter.new }
    let(:spy) { instance_double('Documentz::Uploader::AwsUploader') }
    
    before do 
      allow(Documentz::Uploader::AwsUploader).to receive(:new).and_return(spy) 
    end
    
    it 'calls `s3upload` with the expected arguments' do
      exporter.letsUpLoad
    
      expect(spy).to have_received(:s3upload).with(expected_data_structure)
    end
    

    在 RSpec 文档中了解 custom matches

    顺便说一句。在 Ruby 中,按照惯例,方法名称是用下划线而不是驼峰写的。根据该规则,您的方法应命名为 lets_up_load(或只是 upload)而不是 letsUpLoad

    【讨论】:

    • 这里您正在使用 with(docs: [1,2]) 验证内容。在我的实际用例中,内容不会相同。为简单起见,假设它是随机数。这就是为什么我想弄清楚docs(作为参数传递的数组)的大小是否等于2
    • 我更新了我的答案以解决您的评论。
    • 我正在努力让它工作,但面临一些错误:Failure/Error: Documentz::AwsUploader.new.s3upload(docs: [1,2]) #<InstanceDouble(Documentz::AwsUploader) (anonymous)> received unexpected message :s3upload with ({:docs=>[1, 2]}) 如果我得到一些方向,我会提供适当的更新我也将它保存在 github 上:github.com/sw-dev-ctrl/simply-ruby
    【解决方案2】:

    在这里,您已经模拟了一个接收特定参数的方法,此外,您需要返回一个文档 ID 数组(假设这是您的 s3upload 方法将返回的内容)

    allow_any_instance_of(Documentz::Uploader::AwsUploader).to receive(:s3upload).with( {:docs=>[1,2]}).and_return([1,2])
        
    expect(exp.letsUpLoad.length).to eq 2
    

    【讨论】:

    • 感谢您的回复,我需要检查何时从letsUpload 调用s3upload 一个size=2 的数组应该被发送到s3upload。所以问题是关于输入参数的。除了这两个函数不返回任何东西。
    猜你喜欢
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2015-02-20
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2012-03-18
    相关资源
    最近更新 更多