0
votes

I tried to google but I find nowhere about this error for ActionView I am using Minitest (no Rspec)

custom_user_groups_helper_test.rb

class CustomUserGroupsHelperTest < ActionView::TestCase
    test "should work custom user" do
      response_params  = gotta_get
   end
end

custom_user_groups_helper.rb

 module CustomUserGroupsHelper

  def self.gotta_get
    return true
  end

This test_helper.rb works fine with the controller test, but when I use it for helper test it throws me this error

Error:
CustomUserGroupsHelperTest#test_should_work_custom_user:
NoMethodError: undefined method `env' for nil:NilClass

I tried another solution too

"undefined method `env' for nil:NilClass" in 'setup_controller_for_warden' error when testing Devise using Rspec

But this seems to be for the controller, none of the solutions is for the helper testing. What to include for ActionView::TestCase from Devise

I tried to include these

include Devise::TestHelpers
include Devise::Test::IntegrationHelpers
include Devise::Test::ControllerHelpers

As one of the solutions on StackOverflow says

The Devise::TestHelpers should only be included for controller tests, so you need to move it to the ActionController::TestCase by adding this to your test helpers:

  1. Then what to include for Helper test which inherits ActionView::TestCase
  2. How to test helpers in the Minitest framework.

But i suppose include Devise::Test::IntegrationHelpers and include Devise::Test::ControllerHelpers are for controllers for different rails versions.

error

enter image description here

Updated error stack trace

enter image description here

stack trace for test run

    CustomUserGroupsHelperTest: test_should_work_custom_user
    --------------------------------------------------------
    (0.1ms)  ROLLBACK
  E    (0.1ms)  BEGIN
1
Hi @summu. Possible to share more detailed error logs?Anuj
@basilisk added screenshot class name is CustomUserGroupsHelperTestsummu
This code does not even belong in a helper to begin with. Rather it belongs in just a regular controller concern or a series of service objects. And probably about half belongs in the models. Trying to test this with ActionView::TestCase is just a waste of time as it's for testing actual helpers.max
@max i agree thats a wrong code in helpers, but it that the reason for this error NoMethodError: undefined method `env' for nil:NilClasssummu
Yes. You have a garbage drawer full of controller code and you're trying to test it with ActionView::TestCase and you're trying to test a helper like its a controller. There is nothing right here at all. Take a step back and refactor this into something that can actually be tested and test it at the right level. That nil error is just the tip of the iceberg.max

1 Answers

1
votes

You seem to have fundamentially missunderstood both what a helper is in Rails and how you should test them. Which is really understandable as its a really vague term and means different things in different contexts.

Helpers (as in /app/helpers) in a Rails app are just modules that are mixed into the view context and and provide simple helper methods for stuff like generating html or getting the user from the session in the case of Devise.

A test like this:

require 'test_helper'
class CustomUserGroupsHelperTest < ActionView::TestCase
  test "should work custom user" do
    post :save_custom_groups
    assert_equal "save_custom_groups", @controller.action_name
  end
end

Is just wrong in every way possible. A helper does not respond to HTTP methods. This is more like the strangest attempt at a controller test ever created.

To test helpers you should just test it like a plain old method. Give it input and test the output:

module ListHelper
  def ul(array)
    content_tag :ul do
      array.each do |obj|
        concat content_tag :li, obj
      end
    end
  end
end

class ListHelperTest < ActionView::TestCase
  test "should return the user's full name" do
    assert_dom_equal %{<ul><li>foo</li><li>bar</li></ul>}, ul(["foo", "bar"])
  end
end

If you are testing a helper that relies on a method from Devise like current_user, user_signed_in? etc you should just stub these methods. A helper test is not full stack and thus has no real session.

You can stub other helper methods in ActionView::TestCase by stubbing them on self. If you are using mocha for example you would do:

class UsersHelperTest < ActionView::TestCase

  def setup
    @user = users(:david)
    self.stubs(:current_user).returns(@user)
  end

  test "should link to the current user" do
    assert_dom_equal %{<a href="/user/#{@user.id}">@user.name</a>}, link_to_current_user
  end
end

Devise::Test::IntegrationHelpers and Devise::Test::ControllerHelpers are for integration and controller tests where you are actually driving most of the framework and are completely irrelevant for helper tests. These are examples of test helpers which is a behavior that you mix into your tests.

You can of course test helpers indirectly with integration tests that render the view where the helper is used but since helpers are relatively simple it it can be a good idea to test them directly.