Reputation: 16242
I have a file api_extensions.rb in features/support:
require 'rubygems'
require 'mechanize'
require 'json'
module ApiExtensions
def initialize
@agent = Mechanize.new
@api_header = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}
@api_uris = {
'the list of campuses' => 'http://example.com/servicehosts/campus.svc',
'the list of settings' => 'http://example.com/servicehosts/setting.svc',
'login' => 'http://example.com/servicehosts/Student.svc/login',
}
end
end
World(ApiExtensions)
However, I am still getting the error undefined method '[]' for nil:NilClass (NoMethodError)
on the second line of step definitions file when I run cucumber:
When /^I attempt to log in using a valid username and password$/ do
api_uri = @api_uris['login']
request_body = {:username => "[email protected]", :password => "testsecret"}.to_json
@page = @agent.post(api_uri, request_body, @api_header)
end
Why is the instance variable @api_uris
not showing up even after I have added its module to World? Also, I have tested that the module is being executed by adding some instrumentation to that file, so @api_uris
is being set, it's just not available to my step defintions.
Finally, if I explicitly include ApiExtensions
as the first line of my step definitions file, it works fine. But I thought the call to World(ApiExtensions)
was supposed to automatically include my module in all step definitions file.
Thanks!
Upvotes: 1
Views: 1217
Reputation: 46846
The Problem: My understanding is that World(ApiExtensions)
is extending the world object (see https://github.com/cucumber/cucumber/wiki/A-Whole-New-World). This extension will make the ApiExtensions methods (ie your initialize()) now be available to your steps. You would still need to actually call the initialize method before the instance variables get created and become available to all your steps. If you add initialize
to the start of your step, your step should work.
Solution: If you want to initialize those instance variables when extending the World, you should change your module to:
module ApiExtensions
def self.extended(obj)
obj.instance_exec{
@agent = Mechanize.new
@api_header = {'Accept' => 'application/json', 'Content-Type' => 'application/json'}
@api_uris = {
'the list of campuses' => 'http://example.com/servicehosts/campus.svc',
'the list of settings' => 'http://example.com/servicehosts/setting.svc',
'login' => 'http://example.com/servicehosts/Student.svc/login',
}
}
end
end
When the world object is extending with your module, the self.extended(obj)
method will immediately run and initialize all the variables, making them available to all your steps.
Upvotes: 3