I've run into another set of problems with the two solutions you suggested.
If I go the first way, having the macro method define the example inside of
it, and call that from within a describes block, it appears that any
instance variables declared in the before block of the spec aren't
available. Is this correct behavior?
Alternately, if I instead turn it into a matcher and call it from inside an
it{} block, I'm not able to get proper result messages.
Granted the latter problem is easily ignorable given that the test itself
works, but I'd like to understand both problems anyway.
Here's the code both ways, first, as a matcher:
# spec/support/api_macros.rb
RSpec::Matchers.define :require_minimum_request_params do |url, params|
match do |_|
get url
response.status.should == 400
# See https://github.com/dchelimsky/rspec/issues/25
response.body.include?("missing parameter:")
(params.length - 1).times do |i|
params.to_a.combination(i+1).each do |c|
get url, Hash[*c.flatten]
response.status.should == 400
response.body.include?("missing parameter:")
end
end
get url, params
response.status.should == 200
!response.body.include?("missing parameter:")
end
failure_message_for_should do
"expected URL #{url} to require #{params.keys.join(', ')} as the
minimum parameters"
end
failure_message_for_should_not do
"expected URL #{url} to not require #{params.keys.join(', ')} as the
minimum parameters"
end
description do
"require minimum parameters #{params.keys.join(', ')} for requests to
URL #{url}"
end
end
# spec/requests/api/api_v1.rb
describe MyApp::API_v1 do
before do
@minimum_params = {
api_key: "",
nonce: "",
timestamp: "",
hmac_digest: ""
}
end
context "originator" do
describe "GET /api/v1/originator/hello" do
it { should
require_minimum_request_params("/api/v1/originator/hello", @minimum_params)
}
end
end
end
# $ rspec spec/requests/api/api_v1_spec.rb
MyApp::API_v1
originator
GET /api/v1/originator/hello
should == 200
And instead as a macro:
# spec/support/api_macros.rb
module ApiMacros
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def it_should_require_minimum_request_params(url, params)
it "should require minimum request params" do
get url
response.status.should == 400
response.body.should include("missing parameter")
(params.length - 1).times do |i|
params.to_a.combination(i + 1).each do |c|
get url, Hash[*c.flatten]
response.status.should == 400
response.body.should include("missing parameter")
end
end
get url, params
response.status.should == 200
response.body.should_not include("missing parameter")
end
end
end
end
# spec/requests/api/api_v1.rb
describe MyApp::API_v1 do
before do
@minimum_params = {
api_key: "",
nonce: "",
timestamp: "",
hmac_digest: ""
}
end
context "originator" do
describe "GET /api/v1/originator/hello" do
it_should_require_minimum_request_params("/api/v1/originator/hello",
@minimum_params)
end
end
end
# $ rspec spec/requests/api/api_v1_spec.rb
Failure/Error: (params.length - 1).times do |i|
NoMethodError:
undefined method `length' for nil:NilClass
# ./spec/support/api_macros.rb:13:in `block in
it_should_require_minimum_request_params
On Monday, December 3, 2012 5:42:08 PM UTC-5, Chris Bloom wrote:
>
> Ah, OK. I see the difference now. Thanks for the clarification.
>
> On Monday, December 3, 2012 3:33:42 PM UTC-5, [email protected] wrote:
>>
>> On Mon, Dec 3, 2012 at 2:10 PM, Chris Bloom <[email protected]> wrote:
>> > I'm trying to refactor some common code used in a bunch of requests
>> specs
>> > into a macro, but every way I've tried so far ends in an error saying
>> it
>> > can't find the macro method, or if it can then it can't find the `get`
>> > method. Can someone point me to an example of how to do this?
>> >
>> > # spec/requests/api/api_v1.rb
>> > describe MyApp::API_v1 do
>> > context "originator" do
>> > describe "GET /api/v1/originator/hello" do
>> > it_should_check_minimum_protected_api_params
>> > "/api/v1/originator/hello"
>> > end
>> > end
>> > end
>> >
>> > # spec/support/api_macros.rb
>> > module ApiMacros
>> > def self.included(base)
>> > base.extend(GroupMethods)
>> > end
>> >
>> > module GroupMethods
>> > def it_should_check_minimum_protected_api_params(url)
>> > get url
>> > ...
>> > end
>> > end
>> > end
>> >
>> > # spec/spec_helper.rb
>> > RSpec.configure do |config|
>> > config.include ApiMacros, :type => :request
>> > end
>> >
>> > This ends in:
>> >
>> > $ rspec spec/requests/api
>> > /spec/support/api_macros.rb:8:in
>> > `it_should_check_minimum_protected_api_params': undefined method `get'
>> for
>> > #<Class:0x000001036708f0> (NoMethodError)
>>
>> That's not saying it can't find the macro method. It says it can't find
>> `get`.
>>
>> The macro is being evaluated at the class level, whereas "get" is an
>> instance method. The macro needs to define examples that use the get
>> method, e.g:
>>
>> def it_should_check_minimum_protected_api_params(url)
>> it "should check minimum protected api params" do
>> get url
>> # ...
>> end
>> end
>>
>> HTH,
>> David
>>
>
--
You received this message because you are subscribed to the Google Groups
"rspec" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
To view this discussion on the web visit
https://groups.google.com/d/msg/rspec/-/R3BPlOkxEZIJ.
For more options, visit https://groups.google.com/groups/opt_out.