activeresource model rspec

Given: certain API to obtain merchant information: “/service/merchant/:merchantId”
When: it is called with the merchant id,
Then: it returns a json response like the following:

{"store": {
  "preferences" : [{
    "settings" : [
      {
        "key": "logo",
        "value": "logo.png"
      },
      {
        "key": "text",
        "value": "Hi, welcome to our store"
      },
      {
        "key": "url",
        "value": "http://somestore.com"
      }]
    }]
}}

Then: turn the store settings into a hash like the following:

{:logo => "logo.png", :text =>"Hi, welcome to our store", :url => "http://somestore.com"}

Assuming that we already have a method called get_merchant_info that performs the above task – turning the json response into a hash containing the information.

rspec

describe "#get_merchant_info" do
  context "when the service returns a 200 - data found" do
    it "returns a Hash containing the merchant's information" do
      api_data = {:logo => "logo.png", :text =>"Hi, welcome to our store", :url => "http://somestore.com"}
      
      # settings = mock('settings', <TODO: hash that resembles the json response>  )
      store = mock('store', {:preferences =>[settings]})
      MerchantService.any_instance.should_receive(:store).at_least(1).times.and_return(store)

      merchant = MerchantService.new
      merchant.get_merchant_info.should be_kind_of(Hash)
      merchant.get_merchant_info.should eq(api_data)
    end
  end
end

note: MerchantService is the model that integrates with the API and receives the json response.

The reason I set up api_data at the beginning is so I can reuse it for both json response and the hash result.

Now how do we turn api_data into a hash that resembles the json response (for line 6 above)?

After taking a look at Enumerable – http://apidock.com/ruby/Enumerable, I decided to use collect

So I test it out via the console/irb:

api_data.collect{|k,v| {"key" => k.to_s, "value" => v}}
 => [{"key"=>"logo", "value"=>"logo.png"}, {"key"=>"text", "value"=>"Hi, welcome to our store"}, {"key"=>"url", "value"=>"http://somesite.com"}] 

yayyy! Just what we’re looking for.

But is our test efficient? Personally, I don’t like how we’re mocking twice and stubbing the response, why don’t we set up the response like so…

describe "#get_merchant_info" do
  context "when the service returns a 200 - data found" do
    it "returns a Hash containing the merchant's information" do
      api_data = {:logo => "logo.png", :text =>"Hi, welcome to our store", :url => "http://somestore.com"}
      merchant = MerchantService.new({:store =>
                                          {:preferences => [{
                                                :settings =>
                                                    api_data.collect { |k, v| {"key" => k.to_s, "value" => v} }
                                           }]} })
      merchant.get_merchant_info.should be_kind_of(Hash)
      merchant.get_merchant_info.should eq(api_data)
    end
  end
end

which way do you think is better? hmm? or maybe you can think of a way that’s even better? let me know (;

Advertisements

would you like to leave a comment?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s