1

我在功能/支持中有一个文件 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)但是,当我运行 cucumber 时,我仍然在步骤定义文件的第二行收到错误:

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

为什么@api_uris即使在我将其模块添加到 World 之后,实例变量也没有显示?此外,我已经通过向该文件添加一些工具来测试该模块正在执行,因此@api_uris正在设置,它只是不适用于我的步骤定义。

最后,如果我明确地include ApiExtensions作为我的步骤定义文件的第一行,它工作正常。但我认为调用World(ApiExtensions)应该自动将我的模块包含在所有步骤定义文件中。

谢谢!

4

1 回答 1

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

当世界对象与您的模块一起扩展时,该self.extended(obj)方法将立即运行并初始化所有变量,使它们可用于您的所有步骤。

于 2012-07-14T03:13:16.057 回答