vendredi 22 juillet 2016

ruby rspec mocks test function receiving a hash

I am toying with the mailgun API, all functionalities seem to work now and I want to test them using rspec mocks.

I made some json fixtures under the rspec/fixtures folder, each has a json representing the expected result when I call a particular function. I also made a small helper:

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

What I want to test is this function:

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

Which uses this helper to fetch events:

def self.get_events_for(email:, event_type: "delivered")
    delivered_to_target = []
    response = RestClient.get "https://api:#{configuration.api_key}"\
    "@http://ift.tt/2aiwPqH",
    :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

And here in my spec I have:

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

However, when I tried to run rspec, it always has the following fail trace:

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)>'

I thought I stubbed out the RestClient::Request.execute method so it should work but it didn't. Any ideas on how I can correctly test this function? I'm new to rspec. Thanks

Aucun commentaire:

Enregistrer un commentaire