22

从 ActionView::TestCase 似乎无法访问它们

4

5 回答 5

35

没错,辅助方法不会在视图测试中公开 - 但它们可以在您的功能测试中进行测试。由于它们是在控制器中定义的,因此这是测试它们的正确位置。您的辅助方法可能定义为private,因此您必须使用 Ruby 元编程来调用该方法。

应用程序/控制器/posts_controller.rb:

class PostsController < ApplicationController

  private

  def format_something
    "abc"
  end
  helper_method :format_something
end

测试/功能/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
于 2010-03-22T14:52:33.250 回答
5

这感觉很尴尬,因为您通过在私有方法上使用 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
于 2013-11-25T16:44:04.580 回答
2

您可以@controller.view_context从功能/控制器测试中进行测试。据我所知,此方法在 Rails 3、4 和 5 中可用。

应用程序/控制器/application_controller.rb

class ApplicationController < ActionController::Base
  helper_method :current_user
  # ...
end

测试/控制器/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

如果您不想测试您的控制器子类之一,您还可以创建一个测试控制器来验证 view_context 中的方法与来自控制器的方法相同,而不是来自您的视图助手之一。

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
于 2016-11-05T22:41:07.610 回答
1

我为此苦苦挣扎了一会儿,因为接受的答案实际上并没有测试该方法是否作为辅助方法公开。

也就是说,我们可以使用该#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
于 2018-01-11T10:13:18.957 回答
0

事实上他们不是。视图测试专门针对视图。他们不加载控制器。
您应该模拟此方法并使其根据您的上下文返回适当的内容。

于 2010-03-15T15:29:16.203 回答