Ruby on rails 在capybara功能测试中不总是调用中间件(使用机架测试)

Ruby on rails 在capybara功能测试中不总是调用中间件(使用机架测试),ruby-on-rails,capybara,rack-test,Ruby On Rails,Capybara,Rack Test,我有一个正在开发的gem,它使用railtie添加中间件。非常简单的东西,几乎完全遵循rails指南部分。在开发/分期/生产中工作良好 中间件在env中的特定键处初始化类似散列的对象 但是在我的水豚测试中,这个密钥只是有时初始化的。我在中间件中添加了一个调试器,发现并不是每次使用visit方法时都会调用它 # railtie.rb module MyGem class Railtie < Rails::Railtie initializer "my_gem.configure_

我有一个正在开发的gem,它使用railtie添加中间件。非常简单的东西,几乎完全遵循rails指南部分。在开发/分期/生产中工作良好

中间件在
env
中的特定键处初始化类似散列的对象

但是在我的水豚测试中,这个密钥只是有时初始化的。我在中间件中添加了一个调试器,发现并不是每次使用
visit
方法时都会调用它

# railtie.rb
module MyGem
  class Railtie < Rails::Railtie
    initializer "my_gem.configure_rails_initialization" do |app|
      app.middleware.use MyGem::Middleware
    end
  end
end

# middleware.rb
module MyGem
  class Middleware
    def initialize(app, options={})
      @app = app
      # options unused
    end

    def call(env)
      # using a special internal version of the Rack::Session::Cookie class
      session = MyGem::Rack::Session::Cookie.new(
        @app,
        :coder => MyGem::Rack::Session::Cookie::Base64::Marshal.new,
        :key => ENV_SESSION_KEY,
        :path => '/',
        :domain => domain(env),
        :expire_after => 6.weeks.to_i, # seconds till this expires
        :secret => 'my_gem_secret_14f1c4ad25a6be00fe53f5fd2d746167',
      )

      # use Rack::Session:Cookie method
      session.context(env, @app)
    end
  end
end
更重要的是,在这个特定的spec文件中,有4个示例,每个示例调用一次
visit
。但是当我运行spec文件时,中间件有时被调用3次,有时被调用2次。显然,应该为每个请求调用中间件堆栈


tl;dr:有时调用我的capybara功能规范中的
访问
(使用机架测试驱动程序)不会导致调用我的中间件堆栈


帮忙

  • ruby 2.0.0-p353
  • rails 4.0.2
  • 水豚2.2.1
  • 机架测试0.6.2
编辑:这里有一些相关的代码:中间件是如何添加的以及它做什么的。MyGem::Middleware#调用只有在使用Capybara的
visit
方法时才会被调用

# railtie.rb
module MyGem
  class Railtie < Rails::Railtie
    initializer "my_gem.configure_rails_initialization" do |app|
      app.middleware.use MyGem::Middleware
    end
  end
end

# middleware.rb
module MyGem
  class Middleware
    def initialize(app, options={})
      @app = app
      # options unused
    end

    def call(env)
      # using a special internal version of the Rack::Session::Cookie class
      session = MyGem::Rack::Session::Cookie.new(
        @app,
        :coder => MyGem::Rack::Session::Cookie::Base64::Marshal.new,
        :key => ENV_SESSION_KEY,
        :path => '/',
        :domain => domain(env),
        :expire_after => 6.weeks.to_i, # seconds till this expires
        :secret => 'my_gem_secret_14f1c4ad25a6be00fe53f5fd2d746167',
      )

      # use Rack::Session:Cookie method
      session.context(env, @app)
    end
  end
end
#railtie.rb
模块MyGem
类RailtieMyGem::Rack::Session::Cookie::Base64::Marshal.new,
:key=>ENV_SESSION_key,
:path=>“/”,
:domain=>domain(env),
:expire_after=>6.weeks.to_i,#秒后到期
:secret=>my_gem_secret_14f1c4ad25a6be00fe53f5fd2d746167',
)
#使用Rack::Session:Cookie方法
session.context(env,@app)
终止
终止
终止
算出了

我还添加了一个Warden钩子,该钩子期望在用户登录和注销后添加env密钥,如果Warden::Manager中间件是在我的gem中间件之前添加的,那么在运行我的钩子时,它会出错,因为它期望设置env密钥

解决方案是在我的railtie中这样做:

app.middleware.insert_before Warden::Manager, MyGem::Middleware