开发者

How can I validate each item in an array using RSpec's shared example groups?

开发者 https://www.devze.com 2023-03-09 21:29 出处:网络
I\'m building a rest-ish JSON API using Rails, and I\'d like to test the resource representations I\'m getting back from the server.

I'm building a rest-ish JSON API using Rails, and I'd like to test the resource representations I'm getting back from the server.

I want to validate the response in multiple places, so I created a shared example group that describes the stuff I expect to have inside a single resource. It looks something like this:

describe "Widget API" do

  shared_examples_for "a widget resource" do
    subject { resource }
    its ['id'] { should == widget.id }
    its ['name'] { should == widget.name }
    its ['owner'] { should == widget.owner }
  end

  describe "a GET request to /widgets/:id" do
    before(:each) do 
      @widget = Factory(:widget)
      get widget_path(@widget)
    end

    it_behaves_like "a widget resource" do
      let(:widget) { @widget }
      let(:resource) { ActiveSupport::JSON.decode(response.body.strip) }
    end
  end
end

A request is made, and the shared example group is called with both the hashified response body and the original widget object so they can be compared.

This is working pretty well, and I only have one spot to update my tests if I need to add/change something in the widget representation.

The problem I'm having is when I want to validate an arbitrarily sized array of widget resources, say, for example when requesting the index action:

describe "a GET request to /widgets" do
  before(:each) do
    @widgets = [Factory(:widget), Factory(:widget), Factory(:widget)]
    get widgets_path
  end

  ### Something like this would be nice:
  it "responds with an array of widgets" do
    @resources = ActiveSupport::JSON.decode(response.body.strip)
    @widgets.each_with_index 开发者_StackOverflow社区do |widget, index|
      it_behaves_like "a widget resource" do
        let(:widget) { widget }
        let(:resource) { @resources[index] }
      end
    end
  end
end

(This is a bit contrived, but I think it sorta describes what I'm looking for.)

The problem above is that the it_behaves_like method isn't available within the context of an it block, so I get NoMethodErrors thrown at me.

Is there any way to do this type of enumerating over a subject and calling a shared example group on each of the subject's elements? Am I way off base here? Is there a better way to structure this?

Thanks for any suggestions!

-John

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号