在为rails中的控制器进行功能测试时,如何为请求中的测试提供动态应用程序实例变量。
我有一个@station
对象在我的应用程序控制器的before action
中初始化(在所有其他控制器中都可用),但是@station
对象是由域的条目定义的用户例如:blue.mydomain.com
。因此它可能有3种不同的风格,控制器动作params[:id]
仅对某种风格有效。
此外,如果我不为我的测试环境赋予我的@station味道,它将彻底失败: (这里是来自我在application_controller.rb中的before操作中调用的帮助程序的代码)
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
因此,我只能测试蓝色'或者在我之前的动作中切换风味,然后模拟不同的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实例变量?
答案 0 :(得分:0)
assigns :station
只会在执行请求后返回值,即。在get
行之后。在您完成请求之前,没有为该测试运行任何控制器代码。
您也不应该在rspec中使用@vars
,而是使用let
,以及我在下面展示的其他一些内容,many of which I learned from BetterSpecs
假设domain_flavor_picker
是控制器中的一个方法,那么你应该只是模拟它,这样你就可以对它的不同返回值进行不同的测试。因此,这显示了domain_flavor_picker
的返回值之一的上下文,但您要为其他值添加其他上下文:
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
答案 1 :(得分:0)
我的问题是我需要为minitest提供一个初始主机!从@smathy回答我知道我需要一个模拟请求来控制器!
事实证明,如果你知道如何在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对象。