测试控制的实例变量与架::试验和西纳特拉
题
我有一个Sinatra应用程序提供的网页以只读或编辑取决于用户是否已经登录。
控制器的设置一个变量 @can_edit
, 那是用来通过的意见,以隐藏或展示的编辑联系。我怎么可以测试 @can_edit
's值在我的测试?我不知道如何获取在当前实例的控制下架::试验。
我用 class_eval
存根的 logged_in?
方法在控制器,但是我有要检查 last_response.body
我的编辑看看 @can_edit
已经设定或者没有。
我怎么可以测试的价值 @can_edit
直接?
解决方案
不幸的是,我不认为这是可能的,无需修改架::试验。当你提出请求过程中测试架::试验并如下:
- 增加的请求列表的最近的请求
- 创建一个新的实例应用程序和调用它
call
方法 - 增加了应用程序的回应一览表的最近的答复
这很容易访问 last_request
和 last_response
, 但不幸的是没有信息保存的有关国家的应用程序,同时它的运行。
如果你有兴趣在黑客一起一架::测试贴做到这一点,开始看 rack-test/lib/rack/mock_session.rb
在线30。这是那架::试验运行的应用程序和接收标准架的应用程序的返回值(状况报头、身体)。我猜你会需要修改应用程序以及收集和使访问其所有实例中的变量。
在任何情况下,最好测试的结果,不执行的详细信息。如果你想要确定一个编辑链路是不可见的,测试是否存在编辑的链接,通过DOM id:
assert last_response.body.match(/<a href="..." id="...">/)
其他提示
有可能用少量的黑客。因为当西纳特拉:: Base的#呼叫被称为他们创造了西纳特拉的应用程序的情况下是不可用的。亚历克斯解释说。这对黑客提前准备一个实例,让下一个电话抢了。
require 'something/to/be/required'
class Sinatra::Base
@@prepared = nil
def self.onion_core
onion = prototype
loop do
onion = onion.instance_variable_get('@app')
return onion if onion.class == self || onion.nil?
end
end
def self.prepare_instance
@@prepared = onion_core
end
# Override
def call(env)
d = @@prepared || dup
@@prepared = nil
d.call!(env)
end
end
describe 'An Sinatra app' do
include Rack::Test::Methods
def app
Sinatra::Application
end
it 'prepares an app instance on ahead' do
app_instance = app.prepare_instance
get '/foo'
app_instance.instance_variable_get('@can_edit').should be_true
end
end
我想出这种技术来嘲笑运行在第一位置的当前测试中的实例。
下面有一个讨厌的但可行的替代方案
# app.rb - sets an instance variable for all routes
before do
@foo = 'bar'
end
# spec.rb
it 'sets an instance variable via before filter' do
my_app = MySinatraApplication
expected_value = nil
# define a fake route
my_app.get '/before-filter-test' do
# as previously stated, Sinatra app instance isn't avaiable until #call is performed
expected_value = @foo
end
my_app.new.call({
'REQUEST_METHOD' => 'GET',
'PATH_INFO' => '/before-filter-test',
'rack.input' => StringIO.new
})
expect(expected_value).to eq('bar')
end
这允许测试针对之前为基本应用程序创建的过滤器和或访问实例变量一个屈。