简体   繁体   中英

Minitest - NoMethodError: undefined method `get'

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:in block (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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM