1

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 => "test1@test.com", :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!

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 に答える