当你
require
一个文件,ruby相对于中的路径进行搜索
$LOAD_PATH
;规范/或测试/不是其中的一部分。
app
目录是rails中的一个特殊目录,任何子目录都会自动成为
autoload_paths
。此处可以看到自动加载路径
ActiveSupport::Dependencies.autoload_paths
。
内部定义的任何类/模块
app/*
目录可以在不需要相应文件的情况下使用。Rails v7使用
zeitwerk
通过依赖“文件名”与“常量名”的关系自动加载/重新加载文件。这就是为什么文件夹映射到名称空间,文件映射到类/模块。
要解决您的问题,请将任何共享代码放在可以获取的位置
要求
类型
$LOAD_PATH
在控制台中:
>> $LOAD_PATH
=>
["/home/alex/code/stackoverflow/lib",
"/home/alex/code/stackoverflow/vendor",
"/home/alex/code/stackoverflow/app/channels",
"/home/alex/code/stackoverflow/app/controllers",
"/home/alex/code/stackoverflow/app/controllers/concerns",
"/home/alex/code/stackoverflow/app/helpers",
"/home/alex/code/stackoverflow/app/jobs",
"/home/alex/code/stackoverflow/app/mailers",
"/home/alex/code/stackoverflow/app/models",
"/home/alex/code/stackoverflow/app/models/concerns",
"/home/alex/code/stackoverflow/engines/question/lib", # <= engine's lib looks good
"/home/alex/code/stackoverflow/engines/question/app/components",
"/home/alex/code/stackoverflow/engines/question/app/controllers",
"/home/alex/code/stackoverflow/engines/question/app/controllers/concerns",
...
将共享文件放在引擎的lib目录中。既然我们在外面
应用程序
目录,rails不再是老板,任何路径和文件名组合都可以工作。
# question/lib/testing_support/blah.rb # <= note the filename
module System
def log_visitor_in
administrator = create(:visitor)
visit ccs_cms.login_url
fill_in 'login_name', with: visitor.login_name
fill_in 'Password', with: visitor.password
click_button 'Login'
end
end
现在该文件可能是必需的
# test/test_helper.rb or spec/rails_helper.rb
# after environment and rails requires
require "testing_support/blah" # => loads System module
# ...
就是这样,在你的规范中使用它
require 'rails_helper'
RSpec.describe "order_payment_feature", type: :system do
include System # include is for modules; now we have its functions in this spec
before { log_visitor_in }
it 'should accept this answer' do
visit 'questions/71362333'
expect(page).to have_content('accepted')
end
end
此外,无论
$LOAD_PATH
。
require EngineOne::Engine.root + 'spec/support/system/order_functions.rb'
# or something else
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each { |f| require f }