我的before_filter
课程上有ApplicationController
,我想为它编写测试?我应该把这个测试写在哪里?我不想进入每个子类控制器测试文件并重复关于此过滤器的测试。
因此,测试ApplicationController
before_filters的推荐方法是什么?
请注意,我将Rails 3.2.1
与minitest
一起使用。
答案 0 :(得分:6)
我的情况与您的情况略有不同,但我需要做一些类似于整个网站测试身份验证的事情(使用Devise)。我是这样做的:
# application_controller.rb
class ApplicationController < ActionController::Base
before_filter :authenticate_user!
end
# application_controller_test.rb
require 'test_helper'
class TestableController < ApplicationController
def show
render :text => 'rendered content here', :status => 200
end
end
class ApplicationControllerTest < ActionController::TestCase
tests TestableController
context "anonymous user" do
setup do
get :show
end
should redirect_to '/users/sign_in'
end
end
如果需要跳过前置过滤器的特定控制器,我将进行测试以确保它们在特定控制器的测试中跳过它。这不是你的情况,因为我对该方法的效果感兴趣,而不仅仅是知道它被调用,但我想我会分享以防你发现它有用。
答案 1 :(得分:2)
改进@bmaddy应答器,您需要为要运行的规范设置路由。
以下是rails 5的工作示例:
require 'test_helper'
class BaseController < ApplicationController
def index
render nothing: true
end
end
class BaseControllerTest < ActionDispatch::IntegrationTest
test 'redirects if user is not logedin' do
Rails.application.routes.draw do
get 'base' => 'base#index'
end
get '/base'
assert_equal 302, status
assert_redirected_to 'http://somewhere.com'
Rails.application.routes_reloader.reload!
end
test 'returns success if user is loggedin' do
Rails.application.routes.draw do
get 'base' => 'base#index'
end
mock_auth!
get '/base'
assert_equal 200, status
Rails.application.routes_reloader.reload!
end
end
答案 2 :(得分:1)
我现在相信我必须让我的所有控制器测试关于before_filter存在的测试,并且此过滤器按预期工作。这是因为,我不知道控制器是否应该使用skip_before_filter
。
因此,我决定使用mock
(@controller.expects(:before_filter_method)
)来确保调用过滤器。因此,例如,在我的测试中写的index
动作:
test "get index calls the before filter method" do
@controller.expects(:before_filter_method)
# fire
get :index
end
这将确保我的控制器在特定操作上调用before_filter_method
。我必须在我的所有行动测试中这样做。
如果其他人有更好的解决方案,请告诉我。
答案 3 :(得分:0)
通常当我想要这样的东西时,我只是测试预期的行为而不考虑这个特定的行为可能在过滤器中实现而不是在方法本身中实现。因此,对于以下简单场景:
class Controller < ApplicationController
before_filter :load_resource, :only => [:show, :edit]
def show
end
def edit
end
def index
end
#########
protected
#########
def load_resource
@resource = Model.find(params[:id])
end
end
我会简单地测试#show和#edit分配@resource的东西。这适用于简单的场景,非常好。如果过滤器应用于许多操作/控制器,那么您可以提取测试代码并在测试中重复使用。