我在features / support中有一个文件api_extensions.rb:
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)
但是,当我运行黄瓜时,我仍然在第二行步骤定义文件中收到错误undefined method '[]' for nil:NilClass (NoMethodError)
:
When /^I attempt to log in using a valid username and password$/ do
api_uri = @api_uris['login']
request_body = {:username => "test1@test.com", :password => "testsecret"}.to_json
@page = @agent.post(api_uri, request_body, @api_header)
end
为什么即使我将其模块添加到World后,实例变量@api_uris
也没有显示?另外,我已经通过向该文件添加一些检测来测试模块正在执行,因此@api_uris
正在设置,它只是我的步骤定义不可用。
最后,如果我明确include ApiExtensions
作为我的步骤定义文件的第一行,它可以正常工作。但我认为对World(ApiExtensions)
的调用应该自动将我的模块包含在所有步骤定义文件中。
谢谢!
答案 0 :(得分:3)
问题:我的理解是World(ApiExtensions)
正在扩展世界对象(请参阅https://github.com/cucumber/cucumber/wiki/A-Whole-New-World)。此扩展将使ApiExtensions方法(即您的initialize())现在可用于您的步骤。在创建实例变量之前,您仍然需要实际调用initialize方法,并且可用于所有步骤。如果您将initialize
添加到步骤的开头,那么您的步骤应该有效。
<强>解决方案:强> 如果要在扩展World时初始化这些实例变量,则应将模块更改为:
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
当world对象随模块一起扩展时,self.extended(obj)
方法将立即运行并初始化所有变量,使其可用于您的所有步骤。