ActionView::TestCaseからはアクセスできないようです
5 に答える
そうです、ヘルパーメソッドはビューテストでは公開されていませんが、機能テストでテストすることはできます。そして、それらはコントローラーで定義されているので、これはそれらをテストするのに適切な場所です。ヘルパーメソッドはおそらくとして定義されprivate
ているため、Rubyメタプログラミングを使用してメソッドを呼び出す必要があります。
app / controllers / posts_controller.rb:
class PostsController < ApplicationController
private
def format_something
"abc"
end
helper_method :format_something
end
test /functional/posts_controller_test.rb:
require 'test_helper'
class PostsControllerTest < ActionController::TestCase
test "the format_something helper returns 'abc'" do
assert_equal 'abc', @controller.send(:format_something)
end
end
プライベートメソッドでsendを使用してカプセル化を回避しているため、これは厄介な感じがします。
より良いアプローチは、ヘルパーメソッドを/ controller / concernsディレクトリのモジュールに配置し、このモジュール専用のテストを作成することです。
例:アプリコントローラー/posts_controller.rb
class PostsController < ApplicationController
include Formattable
end
app / controller / concerns/formattable.rbにあります
module Concerns
module Formattable
extend ActiveSupport::Concern # adds the new hot concerns stuff, optional
def format_something
"abc"
end
end
end
そしてtest/functional/concerns/formattable_test.rbで
require 'test_helper'
# setup a fake controller to test against
class FormattableTestController
include Concerns::Formattable
end
class FormattableTest < ActiveSupport::TestCase
test "the format_something helper returns 'abc'" do
controller = FormattableTestController.new
assert_equal 'abc', controller.format_something
end
end
@controller.view_context
機能/コントローラーテストからテストできます。この方法は、私が知る限り、Rails 3、4、および5で使用できます。
app / controllers / application_controller.rb
class ApplicationController < ActionController::Base
helper_method :current_user
# ...
end
test / controllers / application_controller_test.rb
require 'test_helper'
class ApplicationControllerTest < ActionController::TestCase
test 'current_user helper exists in view context' do
assert_respond_to @controller.view_context, :current_user
end
end
コントローラのサブクラスの1つをテストしたくない場合は、テストコントローラを作成して、view_contextのメソッドが、ビューヘルパーの1つではなく、コントローラのメソッドと同じであることを確認することもできます。
class ApplicationControllerHelperTest < ActionController::TestCase
class TestController < ApplicationController
private
def current_user
User.new
end
end
tests TestController
test 'current_user helper exists in view context' do
assert_respond_to @controller.view_context, :current_user
end
test 'current_user returns value from controller' do
assert_instance_of User, @controller.view_context.current_user
end
end
または、より可能性が高いのは、リクエストが存在する場合にヘルパーをテストできるようにすることです。
class ApplicationControllerHelperTest < ActionController::TestCase
class TestController < ApplicationController
def index
render plain: 'Hello, World!'
end
end
tests TestController
def with_routing
# http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-with_routing
# http://guides.rubyonrails.org/routing.html#connecting-urls-to-code
super do |set|
set.draw do
get 'application_controller_test/test', to: 'application_controller_test/test#index'
end
yield
end
end
test 'current_user helper exists in view context' do
assert_respond_to @controller.view_context, :current_user
end
test 'current_user returns value from controller' do
with_routing do
# set up your session, perhaps
user = User.create! username: 'testuser'
session[:user_id] = user.id
get :index
assert_equal user.id, @controller.view_context.current_user.id
end
end
end
受け入れられた回答は、メソッドがヘルパーメソッドとして公開されているかどうかを実際にテストしていなかったため、私はこれに少し苦労しました。
そうは言っても、この#helpers
メソッドを使用して、テスト用のプロキシを取得できます。
例えば:
class FooController < ApplicationController
private
def bar
'bar'
end
helper_method :bar
end
次のコマンドでテストできます:
require 'test_helper'
class FooControllerTest < ActionController::TestCase
test 'bar is a helper method' do
assert_equal 'bar', @controller.helpers.bar
end
end
確かにそうではありません。ビューテストは、特にビュー用です。コントローラをロードしません。
このメソッドをモックして、コンテキストに応じて適切なものを返すようにする必要があります。