使用 minitest 在 rails 中设置用于控制器功能测试的请求变量
Set request variables for functional testing of controllers in rails with minitest
在 rails 中对控制器进行功能测试时,如何为请求中的测试提供动态应用程序实例变量。
我有一个 @station
对象,它在我的应用程序控制器中的 before action
中初始化(在所有其他控制器中可用),但是 @station
对象由域条目定义用户的,例如:blue.mydomain.com
。所以它可以有 3 种不同的口味,控制器操作 params[:id]
只对某种口味有效。
此外,如果我不为我的测试环境添加@station 风格,它将完全失败:
(这里的代码来自在我的 application_controller.rb 之前的操作中调用的助手)
def init_station
if Rails.env == "test"
@station=Station.new('blue')
else
@station=Station.new(domain_flavor_picker)
end
end
ApplicationController
....
before_action :init_station
.....
end
因此我只能测试 'blue' 或在我之前的操作中切换风格,然后模拟不同的 id!
测试:
describe MyController do
before do
@id="10215d8da3f4f278cec747f09985b5528ec9e"
end
it "should get index action" do
p assigns(:station) # is nil
get :artist_biography, id: @id, locale: I18n.available_locales.sample
assert_response :success
assert_not_nil assigns(:meta)
assert_not_nil assigns(:nav)
assert_not_nil assigns(:content)
end
end
如您所见,我也需要提供一个语言环境变量。我设法混淆了那个电话 I18n.available_locales.sample
如何动态切换或操作我的@station 实例变量?
assigns :station
只会 return 一个值 在 你做请求之后,即。在 get
行之后。在您完成请求 none 之前,您的控制器代码已 运行 用于该测试。
您也不应该在 rspec 中使用 @vars
,而是使用 let
,以及我在下面显示的其他一些内容,many of which I learned from BetterSpecs
问题的关键
假设 domain_flavor_picker
是你控制器中的一个方法,那么你应该模拟它,这样你就可以对它的不同 return 值进行不同的测试。因此,这显示了 domain_flavor_picker
的 return 值之一的上下文,但您需要为其他值添加其他上下文:
describe MyController do
let(:id) { "10215d8da3f4f278cec747f09985b5528ec9e" }
describe "GET /artist_biography" do
context "when domain_flavor is blue" do
before do
allow(controller).to receive(:domain_flavor_picker) { "blue" } # <-- MOCK!
end
context "when valid id" do
before { get :artist_biography, id: id, locale: I18n.available_locales.sample }
subject { response }
it { is_expected.to be_success }
it "should assign :meta" do
expect(assigns :meta).to be_present # better to have an actual matcher here
end
it "should assign :nav" do
expect(assigns :nav).to be_present # ditto
end
it "should assign :content" do
expect(assigns :content).to be_present # ditto
end
end
end
end
end
我的问题是我需要为 minitest 提供初始主机!从@smathy 的回答我知道我需要控制器的 Mock Request!
事实证明,如果你知道如何在 MiniTest 中设置它是非常容易的!
Rails 提供了一个 ActionDispatch::TestRequest
对象,它本身似乎是一个 Rack::MockRequest
对象:
DEFAULT_ENV = Rack::MockRequest.env_for('/', 'HTTP_HOST' => 'test.host', 'REMOTE_ADDR' => '0.0.0.0', 'HTTP_USER_AGENT' => 'Rails Testing' )
所以我在测试中要做的就是:
before do
@request.env['HTTP_HOST'] = %w(blue.mydomain.com red.mydomain.com green.mydomain.com).sample
end
使用风味域样本初始化我的@station 对象。
在 rails 中对控制器进行功能测试时,如何为请求中的测试提供动态应用程序实例变量。
我有一个 @station
对象,它在我的应用程序控制器中的 before action
中初始化(在所有其他控制器中可用),但是 @station
对象由域条目定义用户的,例如:blue.mydomain.com
。所以它可以有 3 种不同的口味,控制器操作 params[:id]
只对某种口味有效。
此外,如果我不为我的测试环境添加@station 风格,它将完全失败: (这里的代码来自在我的 application_controller.rb 之前的操作中调用的助手)
def init_station
if Rails.env == "test"
@station=Station.new('blue')
else
@station=Station.new(domain_flavor_picker)
end
end
ApplicationController
....
before_action :init_station
.....
end
因此我只能测试 'blue' 或在我之前的操作中切换风格,然后模拟不同的 id!
测试:
describe MyController do
before do
@id="10215d8da3f4f278cec747f09985b5528ec9e"
end
it "should get index action" do
p assigns(:station) # is nil
get :artist_biography, id: @id, locale: I18n.available_locales.sample
assert_response :success
assert_not_nil assigns(:meta)
assert_not_nil assigns(:nav)
assert_not_nil assigns(:content)
end
end
如您所见,我也需要提供一个语言环境变量。我设法混淆了那个电话 I18n.available_locales.sample
如何动态切换或操作我的@station 实例变量?
assigns :station
只会 return 一个值 在 你做请求之后,即。在 get
行之后。在您完成请求 none 之前,您的控制器代码已 运行 用于该测试。
您也不应该在 rspec 中使用 @vars
,而是使用 let
,以及我在下面显示的其他一些内容,many of which I learned from BetterSpecs
问题的关键
假设 domain_flavor_picker
是你控制器中的一个方法,那么你应该模拟它,这样你就可以对它的不同 return 值进行不同的测试。因此,这显示了 domain_flavor_picker
的 return 值之一的上下文,但您需要为其他值添加其他上下文:
describe MyController do
let(:id) { "10215d8da3f4f278cec747f09985b5528ec9e" }
describe "GET /artist_biography" do
context "when domain_flavor is blue" do
before do
allow(controller).to receive(:domain_flavor_picker) { "blue" } # <-- MOCK!
end
context "when valid id" do
before { get :artist_biography, id: id, locale: I18n.available_locales.sample }
subject { response }
it { is_expected.to be_success }
it "should assign :meta" do
expect(assigns :meta).to be_present # better to have an actual matcher here
end
it "should assign :nav" do
expect(assigns :nav).to be_present # ditto
end
it "should assign :content" do
expect(assigns :content).to be_present # ditto
end
end
end
end
end
我的问题是我需要为 minitest 提供初始主机!从@smathy 的回答我知道我需要控制器的 Mock Request!
事实证明,如果你知道如何在 MiniTest 中设置它是非常容易的!
Rails 提供了一个 ActionDispatch::TestRequest
对象,它本身似乎是一个 Rack::MockRequest
对象:
DEFAULT_ENV = Rack::MockRequest.env_for('/', 'HTTP_HOST' => 'test.host', 'REMOTE_ADDR' => '0.0.0.0', 'HTTP_USER_AGENT' => 'Rails Testing' )
所以我在测试中要做的就是:
before do
@request.env['HTTP_HOST'] = %w(blue.mydomain.com red.mydomain.com green.mydomain.com).sample
end
使用风味域样本初始化我的@station 对象。