ruby rspec模拟测试函数接收哈希值

时间:2016-07-23 04:31:01

标签: ruby testing rspec tdd rspec3

我正在使用mailgun API,所有功能现在似乎都有效,我想使用rspec模拟测试它们。

我在rspec / fixtures文件夹下制作了一些json fixtures,每个都有一个json代表我调用特定函数时的预期结果。我也做了一个小帮手:

module TestHelpers
  def self.get_json(filename:)
    JSON.parse File.read(filename)
  end
end

我想测试的是这个功能:

def self.get_messages_for(email:)
    sent_emails = []
    delivered_events = get_events_for(email: email)

    # :Accept => "message/rfc2822" will help us to get the raw MIME
    delivered_events.each do |event|
      response = RestClient::Request.execute method: :get ,
                                              url: event["storage"]["url"],
                                              user: "api", password:"#{configuration.api_key}",
                                              Accept: "message/rfc2822"
      sent_emails.push(JSON.parse(response))
    end
    sent_emails
  end

使用此帮助程序获取事件:

def self.get_events_for(email:, event_type: "delivered")
    delivered_to_target = []
    response = RestClient.get "https://api:#{configuration.api_key}"\
    "@api.mailgun.net/v3/#{configuration.api_domain}/events",
    :params => {
      :"event" => event_type
    }

    all_delivered = JSON.parse(response)["items"]

    all_delivered.each do |delivered|
      if (delivered.has_key?("recipients") and delivered["recipients"].include?(email)) or
        (delivered.has_key?("recipient") and delivered["recipient"].include?(email))
        delivered_to_target.push(delivered)
      end
    end
    delivered_to_target
  end

在我的规范中,我有:

it 'can get the list of previously sent emails to an email address' do

    allow(StudySoup).to receive(:get_events_for).with({email: email}) {
      Array(TestHelpers::get_json(filename: 'spec/fixtures/events.json'))
    }

    allow(RestClient::Request).to receive(:execute).with(any_args){
      TestHelpers::get_json(filename: 'spec/fixtures/messages.json')
    }

    expect(StudySoup.get_messages_for(email: email)["subject"]).not_to be nil
  end

但是,当我尝试运行rspec时,它总是有以下失败跟踪:

1) StudySoup can get the list of previously sent emails to an email address
     Failure/Error: url: event["storage"]["url"],

     TypeError:
       no implicit conversion of String into Integer
     # ./lib/StudySoup.rb:51:in `[]'
     # ./lib/StudySoup.rb:51:in `block in get_messages_for'
     # ./lib/StudySoup.rb:49:in `each'
     # ./lib/StudySoup.rb:49:in `get_messages_for'
     # ./spec/StudySoup_spec.rb:86:in `block (2 levels) in <top (required)>'

我以为我删除了RestClient::Request.execute方法,所以它应该可以工作,但事实并非如此。关于如何正确测试此功能的任何想法?我试图把许多参数匹配像任何东西(),hash_including(:key =&gt; value)......但它仍然没有用。

1 个答案:

答案 0 :(得分:1)

您确实已经删除了execute方法。这意味着rspec会对该类进行调整,以便调用execute调用rspec的尝试提供代码而不是原始的实现。特别是,该调用的所有参数都被评估为正常。

更改参数匹配器,因为您尝试更改rspec是否决定方法调用与已配置的存根之一匹配,但无法避免评估event["storage"]["url"]引发异常的事实。

当您对get_events_for进行存根时,您返回了一个数组数组而不是一个哈希数组:Array调用to_aryto_a的参数将您的哈希值转换为一组键值对,而不是像我认为的那样将哈希包装在数组中。