Ruby-on-rails Rspec:如何在控制器规范中分配实例变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16005281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:48:53  来源:igfitidea点击:

Rspec: How to assign instance variable in controller spec

ruby-on-railsrspec

提问by ole

class TestController < AplicationController
  #....

  private

  def some_method
    unless @my_variable.nil?
      #...
      return true
    end
  end
end

I want to test some_methoddirectly in controller spec:

我想some_method直接在控制器规范中测试:

require 'spec_helper'

describe TestController do
  it "test some_method"
    phone = Phone.new(...)
    controller.assign(:my_variable,phone) #does not work
    controller.send(:some_method).should be_true
  end
end

How I can set TestControllerinstance variable @my_variablefrom controller spec?

如何从控制器规范设置TestController实例变量@my_variable

回答by Paul Fioravanti

When testing private methods in controllers, rather than use send, I tend to use an anonymous controllerdue to not wanting to call the private method directly, but the interface to the private method (or, in the test below, effectively stubbing that interface). So, in your case, perhaps something like:

在控制器中测试私有方法而不是 use 时send,我倾向于使用匿名控制器,因为不想直接调用私有方法,而是私有方法的接口(或者,在下面的测试中,有效地存根该接口)。所以,在你的情况下,也许是这样的:

require 'spec_helper'

describe TestController do
  controller do
    def test_some_method
      some_method
    end
  end

  describe "a phone test with some_method" do

    subject { controller.test_some_method }

    context "when my_variable is not nil" do
      before { controller.instance_variable_set(:@my_variable, Phone.new(...)) }
      it { should be_true }
    end

    context "when my_variable is nil" do
      before { controller.instance_variable_set(:@my_variable, nil) } 
      it { should_not be_true } # or should be_false or whatever
    end     
  end
end

There's some good discussion on the issue of directly testing private methods in this StackOverflow Q&A, which swayed me towards using anonymous controllers, but your opinion may differ.

此 StackOverflow Q&A 中对直接测试私有方法的问题进行了一些很好的讨论,这使我倾向于使用匿名控制器,但您的意见可能有所不同。

回答by Alex Falke

I don't think you want to access an instance variable from your spec controller, as the spec should test the behaviour, but you can always stub the private method. In your case it should be something like this (in this example it doesn't make so much sense):

我认为您不想从规范控制器访问实例变量,因为规范应该测试行为,但您始终可以存根私有方法。在你的情况下,它应该是这样的(在这个例子中它没有多大意义):

describe TestController do
  it "test some_method"
    phone = Phone.new(...)
    controller.stub(:some_method).and_return(true)
    controller.send(:some_method).should be_true
  end
end

If this is not what you are looking for take a look at this: How to set private instance variable used within a method test?

如果这不是您要查找的内容,请查看:如何设置方法测试中使用的私有实例变量?

回答by ReWrite

instance_evalis a relatively clean way to accomplish this:

instance_eval是实现此目的的相对干净的方法:

describe TestController do
  it "test some_method" do
    phone = Phone.new(...)
    controller.instance_eval do
      @my_variable = phone
    end
    controller.send(:some_method).should be_true
  end
end

In this case, using do...endon instance_evalis overkill, and those three lines can be shortened to:

在这种情况下,使用do...endoninstance_eval是矫枉过正,这三行可以缩短为:

controller.instance_eval {@my_variable = phone}