为minitest中的控制器的功能测试设置请求变量

时间:2015-03-13 15:21:14

标签: ruby-on-rails ruby-on-rails-4 request minitest

在为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实例变量?

2 个答案:

答案 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对象。