class TestController < AplicationController
#....
private
def some_method
unless @my_variable.nil?
#...
return true
end
end
end
我想直接在控制器规范中测试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
如何从控制器规范中设置TestController
实例变量@my_variable
?
答案 0 :(得分:60)
在控制器中测试私有方法时,而不是使用send
,我倾向于使用anonymous controller,因为不想直接调用私有方法,而是私有方法的接口(或者,在下面的测试中,有效地存在该接口)。所以,在你的情况下,可能是这样的:
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
关于在this StackOverflow Q&A中直接测试私有方法的问题有一些很好的讨论,这使我对使用匿名控制器感到不满,但您的意见可能有所不同。
答案 1 :(得分:2)
我认为您不希望从规范控制器访问实例变量,因为规范应该测试行为,但您始终可以存根私有方法。 在你的情况下它应该是这样的(在这个例子中它没有那么多意义):
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
如果这不是你想要的,请看一下:How to set private instance variable used within a method test?
答案 2 :(得分:0)
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
在这种情况下,在do...end
上使用instance_eval
是过度的,这三行可以缩短为:
controller.instance_eval {@my_variable = phone}