Why can't my Rspec integration tests find my modules? - ruby-on-rails

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

Related

Can't stub with mocha in ruby on rails test

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.

Integration testing for image upload

I learned how to test image file uploading from this excellent article:
https://jeffkreeftmeijer.com/2010/2014/using-test-fixtures-with-carrierwave/
Adapting those ideas for my app, I've got this test that works:
test "uploads an image" do
pic = Picture.create(:image => fixture_file_upload('/files/DJ.jpg','image/jpg'), :user => User.first)
assert(File.exists?(pic.reload.image.file.path))
end
I would like to test the same thing for the user interface, so I would think that this test would also pass:
test "create new picture" do
capybara_login(#teacher_1)
click_on("Upload Pictures")
fill_in "picture_name", with: "Apple"
attach_file('picture[image]', Rails.root + 'app/assets/images/apple.png')
check("check_#{#user_l.id}")
check("check_#{#admin_l.id}")
click_on ("Create Picture")
#new_pic = Picture.last
assert_equal "Apple", #new_pic.name
assert #new_pic.labels.include?(#user_l)
assert #new_pic.labels.include?(#admin_l)
assert #teacher_1, #new_pic.user
assert File.exists?(#new_pic.reload.image.file.path)
end
But it fails on the last line, asserting the existence of the file.
Below are the parts of my test_helper that I thought would be relevant. I can show the whole test_helper if someone thinks it necessary.
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"
require 'capybara/rails'
Minitest::Reporters.use!
CarrierWave.root = 'test/fixtures/files'
class CarrierWave::Mount::Mounter
def store!
# Not storing uploads in the tests
end
end
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
include ApplicationHelper
include ActionDispatch::TestProcess
CarrierWave.root = Rails.root.join('test/fixtures/files')
def after_teardown
super
CarrierWave.clean_cached_files!(0)
end
end
Everything appears to be working as expected in development and production.
Thank you in advance for any insight.

minitest-rails - test:helpers - NameError: Unable to resolve controller for ApplicationHelper

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

Undefined method `get' in Minitest

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.

invalid method when including module in Activesupport testcase

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

Resources