0

I was stuck with error when i run very simple test with minitest-rails gem. I have rails 4.1.5 and minitest 5.4.0

rake test:controllers

1) Error: DashboardController::index action#test_0001_anonymous: NoMethodError: undefined method get' for #<#<Class:0x00000008e28170>:0x00000008eeb9b8> test/controllers/dashboard_controller_test.rb:6:inblock (3 levels) in '

Test:

require "test_helper"

describe DashboardController do
  context "index action" do
    before do
      get :index
    end
    it { must_respond_with :success }
    it "must render index view" do
      must_render_template :index
    end
  end
end

My test_helper:

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
require "minitest/rails/capybara"


class MiniTest::Spec
  class << self
    alias :context :describe
  end
end


class RequestTest < MiniTest::Spec
  include Rails.application.routes.url_helpers

  register_spec_type(/request$/, self)
end


class ActionDispatch::IntegrationTest
  # Register "request" tests to be handled by IntegrationTest
  register_spec_type(/Request( ?Test)?\z/i, self)
end

class ActiveSupport::TestCase
  ActiveRecord::Migration.check_pending!

  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
  #
  # Note: You'll currently still have to declare fixtures explicitly in integration tests
  # -- they do not yet inherit this setting
  fixtures :all

  # Add more helper methods to be used by all tests here...
  extend MiniTest::Spec::DSL
end
rootatdarkstar
  • 1,486
  • 2
  • 15
  • 26
  • Looks like you need [this](http://stackoverflow.com/questions/11667552/minitest-undefined-method-get) – dddd1919 Sep 11 '14 at 03:01

1 Answers1

5

There are many things wrong with what you are doing. As I understand it you want to use Minitest's spec DSL in your Rails tests, correct? It looks like you are doing things to accomplish this that you don't need to do. I don't understand why half that code in your test_helper.rb file is there. I also suspect that you have other code doing things that are not being shown.

Here is what I did to reproduce your setup:

$ echo "Creating a new Rails app"
☣ [rails41:rails41] $ rails new undefined_get
☣ [rails41:rails41] $ cd undefined_get/
$ echo "Generate a Dashboard controller"
$ rails g controller dashboard index
$ echo "Add minitest-rails dependencies"
$ echo 'gem "minitest-rails"' >> Gemfile
$ echo 'gem "minitest-rails-capybara"' >> Gemfile
$ bundle install
$ echo "The test runs fine now:"
$ rake test
Run options: --seed 47210

# Running:

.

Finished in 0.457972s, 2.1835 runs/s, 2.1835 assertions/s.

1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
$ echo "Update to your test code and test_helper code"
$ echo "Use whatever editor you want. Not shown here."
$ echo "Now rerun the tests:"
$ rake test
rake aborted!
NoMethodError: undefined method `context' for #<Class:0x007f860258ae50>

The error I get is different than yours. You aliased the method context to describe in your test_helper.rb file, but unfortunately the object you aliased is not in the inheritance chain for the rails test objects. The rails test objects extend Minitest::Spec::DSL, but they do not inherit from Minitest::Spec. So, I am strongly suspicious that the code you provided is indeed producing the results you have presented. That said, here is the code in my test_helper.rb that will run your test:

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/rails"
require "minitest/rails/capybara"

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Allow context to be used like describe
  class << self
    alias :context :describe
  end

  # Add more helper methods to be used by all tests here...
end

This is the standard test_helper.rb with two changes. First, it has the requires for minitest-rails and minitest-rails-capybara. That is all you need to do in order to enable the Minitest spec DSL in your rails tests. Second, it adds the alias for context to describe on ActiveSupport::TestCase, which is the basis for all the rails tests. If you want to add tests that do not inherit from ActiveSupport::TestCase then you can also alias it on Minitest::Spec, but that will not help you use context within your controller tests.

Still here? Okay. So why did your code give you a different error than mine? Likely the test object used for your controller tests isn't ActionController::TestCase. I say that because your error was undefined method get. The get method is something that ActionController::TestCase defines, and is not on Minitest::Spec. So, you somehow messed up your Minitest configuration. A simple way to make sure that your tests are using the correct test objects is to add an additional assertion to your test. Like this:

require "test_helper"

describe DashboardController do
  context "index action" do
    before do
      # Make sure we are using the correct test class
      self.class.ancestors.must_include ActionController::TestCase
      # Continue with setup
      get :index
    end
    it { must_respond_with :success }
    it "must render index view" do
      must_render_template :index
    end
  end
end

If that first assertion fails then you know you have done something wrong in your configuration.

blowmage
  • 8,854
  • 2
  • 35
  • 40