应用程序一切都很好,直到我将其重构为多个控制器/服务器。
我相信我正在使用Sinatra-Base的模块化设置。我相信我已经正确定义了我的机架环境。
我有一个问题。如果不在我的命令行中启动 Sinatra,我就无法运行 rspec。当我通过注释掉服务器文件底部的"run!"命令来解决此问题时,显然当我尝试从命令行运行我的应用程序时,Sinatra不会启动。
这是我的文件结构:
app
app.rb
server.rb
datamapper_setup.rb
controllers
new_users.rb
sessions.rb
views
various.erb
files.erb
models
user.rb
spec
features
feature_test_spec.rb
other_feature_test_spec.rb
units
unit_test_spec.rb
spec_helper.rb
config.ru
.rspec
Gemfile
Rakefile
这是我 config.ru 文件
require './app/app.rb'
run MyApp
这是我的应用程序.rb 文件
ENV['RACK_ENV'] ||= 'development'
require 'rack'
require 'sinatra/base'
require 'sinatra/flash'
require 'sinatra/partial'
require_relative 'data_mapper_setup'
require_relative 'server'
require_relative 'controllers/new_users'
require_relative 'controllers/sessions'
这是我的服务器文件
class App < Sinatra::Base
register Sinatra::Flash
register Sinatra::Partial
enable :sessions
set :session_secret, 'super secret'
set :partial_template_engine, :erb
helpers do
def session_user
@session_user ||= User.get(session[:user_id])
end
end
get '/' do
@new_user = User.new
erb :'user/index'
end
#Here is where I am commenting out run! in order to be able to run rspec without starting Sinatra.
# It doesn't work at all if I have => run! if app_file == $0 now, but used to work before the refactor when this line was in my app file.
run!
end
在我的规范助手中:
ENV['RACK_ENV'] = 'test'
require File.join(File.dirname(__FILE__), '..', 'app/app.rb')
require './app/app.rb'
require 'capybara'
require 'capybara/rspec'
require 'rspec'
require 'database_cleaner'
require 'coveralls'
require 'simplecov'
require './app/data_mapper_setup.rb'
require './spec/web_helpers.rb'
SimpleCov.formatters = [
SimpleCov::Formatter::HTMLFormatter,
Coveralls::SimpleCov::Formatter
]
Coveralls.wear!
Capybara.app = App
RSpec.configure do |config|
config.include SessionHelpers
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.include Capybara::DSL
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
我所有的 rspec 测试都通过了。
我试过什么...
- 各种不同的 config.ru 设置
- Spec_helper 要求"机架"不同
- 检查我的机架环境是否在我的数据库中隔离
- 试图理解Sinatra模块化和Sinatra古典风格之间的区别(成功有限(
每次app.rb
文件时调用.run!
是导致问题的原因。
对此有两个很好的解决方案:
仅在直接运行app.rb
时调用.run
当您不需要调用.run!
时,您可以通过将其包装在条件中来检查app.rb
文件是否已直接运行并且未由其他文件加载。那看起来像这样:
class App < Sinatra::Base
# …
if __FILE__ == $0
run!
end
end
让我们分解一下:
-
__FILE__
是当前文件的路径。 -
$0
是从命令行运行的 Ruby 脚本的路径。
有了这个条件,从命令行运行ruby app.rb
将触发对.run!
的调用,但运行其他命令(如rackup
或rspec
(将意味着$0
与__FILE__
不匹配,因此永远不会调用.run!
。
通过rackup
运行本地服务器
该问题的替代解决方案是完全删除对.run!
的调用,并使用 rackup
命令启动本地开发服务器。
由于您已经有一个config.ru
文件,因此您应该能够在没有参数的情况下运行rackup
以获取正在运行的开发服务器。
这将是我的首选方法,因为这意味着如果您想向应用程序添加更多机架中间件(例如,对用户进行身份验证或提供静态文件(,您可以将它们添加到您的config.ru
文件中,您将在开发和生产中运行它们。
更多阅读
- 辛纳屈第四章:启动和运行