在Sinatra模块化应用程序中设置RSpec

Car*_*eda 3 ruby rspec sinatra

这是我与Sinatra的第一次尝试.我构建了一个简单的经典应用程序,为它设置RSpec,并让它工作.然后,我尝试以MVC方式进行模块化.即使应用程序在浏览器中工作,RSpec也会抛出一个NoMethodError.我已经阅读过关于RSpec的Sinatra文档,在SO中也搜索了很多,但我找不到bug的位置.任何线索?

非常感谢你提前.

这是我的相关文件:

config.ru

require 'sinatra/base'

Dir.glob('./{app/controllers}/*.rb') { |file| require file }

map('/') { run ApplicationController }
Run Code Online (Sandbox Code Playgroud)

app.rb

require 'sinatra/base'

class ZerifApp < Sinatra::Base
  # Only start the server if this file has been
  # executed directly
  run! if __FILE__ == $0
end
Run Code Online (Sandbox Code Playgroud)

应用程序/控制器/ application_controller.rb

class ApplicationController < Sinatra::Base
  set :views, File.expand_path('../../views', __FILE__)
  set :public_dir, File.expand_path('../../../public', __FILE__)

  get '/' do
    erb :index
  end
end
Run Code Online (Sandbox Code Playgroud)

投机/ spec_helper.rb

require 'rack/test'

# Also tried this
# Rack::Builder.parse_file(File.expand_path('../../config.ru', __FILE__))

require File.expand_path '../../app.rb', __FILE__

ENV['RACK_ENV'] = 'test'

module RSpecMixin
  include Rack::Test::Methods
  def app() described_class end
end

RSpec.configure { |c| c.include RSpecMixin }
Run Code Online (Sandbox Code Playgroud)

投机/ app_spec.rb

require File.expand_path '../spec_helper.rb', __FILE__

describe "My Sinatra Application" do
  it "should allow accessing the home page" do
    get '/'
    expect(last_response).to be_ok
  end
end
Run Code Online (Sandbox Code Playgroud)

错误

My Sinatra Application should allow accessing the home page
     Failure/Error: get '/'
     NoMethodError:
       undefined method `call' for nil:NilClass
     # ./spec/app_spec.rb:5:in `block (2 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)

zet*_*tic 5

我猜你正在遵循这个食谱,对吗?

described_class这行:

def app() described_class end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,被认为是被测试的阶级ZerifApp.试试吧:

def app() ZerifApp end
Run Code Online (Sandbox Code Playgroud)

编辑

事实证明,上述答案并不正确described_class.我假设它是一个占位符 - 实际上它是一个RSpec方法,它返回隐式主题的类,也就是说,正在测试的东西.

由于它建议编写describe块的方式,链接上的配方会产生误导:

describe "My Sinatra Application" do
Run Code Online (Sandbox Code Playgroud)

这是有效的RSpec,但它没有定义主题类.执行described_class该块的示例将返回nil.要使其工作,请替换describe块:

describe ZerifApp do
Run Code Online (Sandbox Code Playgroud)

现在described_class将返回预期值(ZerifApp)