I'm fairly new to Ruby/Ruby on Rails and having trouble stubbing out a method via mocha in an existing codebase.
I've simplified the code down to a MWE where this breaks.
Here is test_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require "rails/test_help"
class ActiveSupport::TestCase
end
class Minitest::Test
def before_setup
end
end
And here is the test:
require 'test_helper'
require 'mocha/minitest'
class MyTest < ActionMailer::TestCase
describe "some test" do
it "should stub" do
My::Class.stubs(:bar).returns("foo")
puts My::Class.bar
end
end
end
This results in the following error when I run the test:
Mocha::NotInitializedError: Mocha methods cannot be used outside the context of a test
However, when I redefine my test_helper.rb as follows:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require "rails/test_help"
class ActiveSupport::TestCase
end
# class Minitest::Test
# def before_setup
#
# end
# end
The test passes (and "foo" is printed as expected).
Why does the class Minitest::Test...end in test_helper.rb cause the first error? I can't remove that code from the actual codebase, so how can I modify it to work with mocha?
Ruby version: 2.4.1
Rails version: 4.2.8
Mocha version: 1.5.0
Adding a call to super in the patched method before_setup in test_helper.rb works:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require "rails/test_help"
class ActiveSupport::TestCase
end
class Minitest::Test
def before_setup
# do something
super
end
end
This call to super allows the before_setup of Mocha::Integration::MiniTest to be called, which is necessary for proper initialization.
Related
My app has a default controller abstracted into a gem (gem 'abstracted') and all my controllers inherits from this abstracted controller.
# Gemfile
gem 'abstracted', path: '../../gems/abstracted'
# app/controllers/accounts_controller.rb
class AccountsController < AbstractResourcesController
end
Now when I write controller (mini)tests for one of this controllers like this:
require "test_helper"
describe AccountsController do
...
I get this error once hitting: rake test from the prompt:
NameError: uninitialized constant AbstractResourcesController
/path_to_rails/projects/cas_server/app/controllers/accounts_controller.rb:1:in `<top (required)>'
My test/test_helper.rb looks like this:
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'minitest/autorun'
require 'action_controller/test_case'
require 'capybara/rails'
require 'rails/test_help'
require 'minitest-rails'
require 'minitest/pride'
# require 'miniskirt'
# require 'factories'
# require 'mocha'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
# Add more helper methods to be used by all tests here...
end
class ActionController::TestCase
include Devise::TestHelpers
end
class MiniTest::Unit::TestCase
# include MiniTest::ActiveRecordAssertions
# DatabaseCleaner.strategy = :transaction
#
# def setup
# DatabaseCleaner.start
# end
#
# def teardown
# DatabaseCleaner.clean
# end
end
class MiniTest::Spec
include ActiveSupport::Testing::SetupAndTeardown
# alias :method_name :__name__ if defined? :__name__
def build_message(*args)
args[1].gsub(/\?/, '%s') % args[2..-1]
end
end
class ControllerSpec < MiniTest::Spec
include ActionController::TestCase::Behavior
include Devise::TestHelpers
include Rails.application.routes.url_helpers
# Rails 3.2 determines the controller class by matching class names that end in Test
# This overides the #determine_default_controller_class method to allow you use Controller
# class names in your describe argument
# cf: https://github.com/rawongithub/minitest-rails/blob/gemspec/lib/minitest/rails/controller.rb
def self.determine_default_controller_class(name)
if name.match(/.*(?:^|::)(\w+Controller)/)
$1.safe_constantize
else
super(name)
end
end
before do
#controller = self.class.name.match(/((.*)Controller)/)[1].constantize.new
#routes = Rails.application.routes
end
subject do
#controller
end
end
# Functional tests = describe ***Controller
MiniTest::Spec.register_spec_type( /Controller$/, ControllerSpec )
Add this in your controller spec file before describe AccountsController do,
module AbstractResourcesController
class Base
def self.protect_from_forgery; end
end
end
require 'abstract_resources_controller'
I have strange error when i run my tests for helpers with rake test:helpers
ApplicationHelper::dummy#test_0001_must return string:
NameError: Unable to resolve controller for ApplicationHelper::dummy
Test:
require "test_helper"
describe ApplicationHelper do
include ApplicationHelper
context "dummy" do
it "must return string" do
result = dummy()
result.must_be_kind_of ( String )
result.wont_be_empty
end
end
end
My helper
module ApplicationHelper
def dummy
"hello world".html_safe
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"
require 'minitest/rg'
require "warden_mock"
class ActiveSupport::TestCase
fixtures :all
class << self
alias :context :describe
end
end
class ActionController::TestCase
def setup
request.env['warden'] = WardenMock.new # mockup warden
User.current = request.env['warden'].user
end
register_spec_type(/.*/, self)
end
rails 4.1.6
minitest-rails 2.1.0
Try to comment out require "minitest/rails/capybara" in your test_helper.rb and require it only in your feature tests
I'm trying to create a functional test for my RESTful API with MiniTest:
require 'test_helper'
class AutomaticTests < ActiveSupport::TestCase
test "test1" do
get '/'
end
end
The code above triggers an error:
Minitest::UnexpectedError: NoMethodError: undefined method `get' for
My test_helper.rb looks like this:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/rails"
class ActiveSupport::TestCase
fixtures :all
class << self
alias :context :describe
end
end
How can I make 'get' method work?
Get comes from rack/test, so you will need to add that gem to your Gemfile:
gem 'rack-test', group: :test
And then, in your test file or your test_helper.rb, add the following line:
require "rack/test"
... and ...
class ActiveSupport::TestCase
include Rack::Test::Methods
end
You can also use the rack-minitest gem.
You are inheriting from the wrong test class. Instead of ActiveSupport::TestCase you want to use ActiveDispatch::IntegrationTest.
class AutomaticTests < ActiveDispatch::IntegrationTest
test "test1" do
get '/'
end
end
See the testing guide for more info on the test classes that rails provides.
I created this module: support/mailer_macros.rb
module MailerMacros
def last_email
ActionMailer::Base.deliveries.last
end
def reset_email
ActionMailer::Base.deliveries = []
end
end
I want to access it from my testhelper, so I did this in test/test_helper.rb:
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
#require "capybara/rails"
require "minitest/rails/capybara"
require "support/mailer_macros"
class ActiveSupport::TestCase
include MailerMacros
reset_email
end
But when I run my tests, I get the error:
undefined local variable or method `reset_email' for ActiveSupport::TestCase:Class
What's wrong? Thanks!
Including a module means that the module's methods are available as instance methods, not class methods. You're trying to run reset_email at the class level.
To fix this, extend MailerMacros instead of including it:
class ActiveSupport::TestCase
extend MailerMacros
reset_email
end
I'd like to be able to call login_as_admin and login_as_customer at any point in any spec file.
I have a directory full of integration specs:
/spec/features/area_spec.rb
/spec/features/assignment_spec.rb
/spec/features/etc…
Each of which starts with:
require 'spec_helper'
require 'rspec_macros'
I also have /spec/spec_help.rb, which includes:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require File.dirname(__FILE__) + "/rspec_macros"
And I have /spec/rspec_macros.rb, which includes:
module RspecMacros
def login_as_admin
etc…
end
def login_as_customer
etc…
end
end
Why, then, do I get the following error at the Rspec command line?
Failure/Error: login_as_customer
NameError:
undefined local variable or method `login_as_customer' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2:0x007fd99f471f50>
I believe you either need to make these functions in spec helper or include the modules in your tests.
To include the modules you can do something like this:
module RspecMacros
extend ActiveSupport::Concern
included do
def login_as_customer
...
end
end
end
require 'rspec_macros'
describe MyCoolTest do
include RspecMacros
end
You may find it easier to just make them functions in spec helper. You can just add:
def login_as_customer
....
end
to the end of spec_helper.rb