So, here we have a file with struct,
module CoreDomain
Corporation = Struct.new(...)
end
and we have such a test file,
require 'test_helper'
module CoreDomain
class CorporationTest < ActiveSupport::TestCase
def test_corporation_struct_creation
corp_struct = CoreDomain::Corporation.new(...)
assert_equal ..., ...
end
end
end
when I trying to execute the test I get this error.
NameError: uninitialized constant CoreDomain::Corporation
Question - where I am getting wrong?
What I think is going actually going on here is that you're fooling the autoloader.
Since your test is nested inside module CoreDomain when you get to CoreDomain::Corporation.new(...) it won't trigger the autoloader to start looking for the CoreDomain constant. The classic autoloader worked by hacking its way onto Object.const_missing so was very prone to these kind of errors.
The solution is to just reference the constant before you reopen the module:
require 'test_helper'
CoreDomain::Corporation # take that you stupid autoloader!
module CoreDomain
class CorporationTest < ActiveSupport::TestCase
def test_corporation_struct_creation
corp_struct = Corporation.new(...)
assert_equal ..., ...
end
end
end
Or just remove the test class from the module.
Maybe there was some misunderstanding, but all I need to do is to add this line
require_relative '../../core/domain/corporation.rb'
to the top of test_corporation.rb file
Related
I have these 2 files in a large system, both are located in PackA
people.rb
module People
class HobbyValueObject
end
end
job.rb
module People
class Job
end
class CityValueObject
end
end
I am trying to use CityValueObject in a different module like this,
Module is in PackB
work.rb
module Profile
class Work
....
def calculateTaxes
...
a = People::CityValueObject....
end
end
end
But it's giving me an error saying,
NameError: uninitialized constant People::CityValueObject
Did you mean? People::HobbyValueObject
Why is not being able to fine CityValueObject but can find HobbyValueObject just fine?
How do I make it find the object that I am intending to use?
I am not explicitly declaring any requires or includes
I was able to resolve this by adding require at the top while using full path file name.
require './packs/people/app/public/people/job'
I've just updated my Gemfile.
At the beginning I thought problem came from Zeitwerk (from 2.4.2 to 2.5.4) but I've downgraded it and I still have an issue on my spec. I've isolated that the problem does not come from RSpec and dependencies.
Actually, RSpec does not found a class which is defined within another file and does not match the file name/class name.
Important point: Filter::MyStandardError is found.
# app/services/filter/my_standard_error.rb
module Filter
class MyStandardError < StandardError; end
class MySpecificError < MyStandardError; end
# ...
end
# app/services/filter/my_tested_service.rb
module Filter
class MyTestedService
def initialize
raise ::Filter::MySpecificError
end
end
end
RSpec.describe Filter::MyTestedService do
subject { described_class.new }
it 'raises an error'
expect{subject}.to raise_error(::Filter::MySpecificError)
end
end
And I got the error:
NameError:
uninitialized constant Filter::MySpecificError
I got the Changelog but breaking changes are not used on my configuration.
Does anybody have an idea for this one?
You do not need to add app/services to the autoload paths, that is done automatically by Rails. I'd suggest to remove that configuration to keep things simple/idiomatic.
The implementation of app/services/filter.rb should not be needed. Your application is doing something that is not right, we just need to find it.
Could you please delete app/services/filter.rb, throw Rails.autoloaders.log! in config/application.rb, trigger the error, and share the traces?
After reading one-file-one-constant-at-the-same-top-level
I found this to fix my issue
# app/services/filter.rb
class Filter
class MyStandardError < StandardError; end
class MySpecificError < MyStandardError; end
end
# app/services/filter/my_tested_service.rb
class Filter
class MyTestedService
def initialize
raise ::Filter::MySpecificError
end
end
end
I still don't know why it was working before..
You cannot define two constants at the same level in the same file. It is one constant, one file. This has not changed in Zeitwerk upgrades. You need one file for the standard error, and another file for the specific error.
I'm trying to do something fairly simple - add a module with helper methods to a Model test, but I keep getting the following error
uninitialized constant NeighborhoodTest::NeighboorhoodTestHelper
The module is located in test/helpers/neighborhood_test_helper.rb
module NeighborhoodTestHelper
def create_polygon
points = self.geolocate
boundary = Geokit::Polygon.new(points)
end
.
.
end
Per the recommendation in this SO answer, did the following inside test/models/neighborhood_test.rb:
require 'test_helper'
require 'helpers/neighborhood_test_helper'
class NeighborhoodTest < ActiveSupport::TestCase
include NeighboorhoodTestHelper
def setup
#crime = crimes(:arrest)
#neighborhood = neighborhoods(:one)
end
test "neighborhood should contain crime" do
neighborhood_boundary = #neighborhood.create_polygon
crime_location = #crime.geolocate
assert neighborhood_boundary.contains?(crime_location)
end
end
I also tried this SO that didn't work. Anyone know why this approach doesnt work in Models?
tests/some_helper.rb
module SomeHelper
def method1
-----------
-----------
end
def method2
-----------
-----------
end
end
tests/test_helper.rb
require some_helper.rb
You can now access method1 and method2 in any of your test cases. Hope it helps you .
I ran into this today with rspec 3.8, and with other helper tests working just fine, I was very curious to know what made this one spec so special.
In my case, it turned out the spec file name, for whatever reason, was given the same file name as the helper module itself. When trying to load the constant it was looking in the spec file, since it had taken the place of "my_helper" and in turn ignoring the actual module. Adding a _spec at the end of the spec file name allowed this error to go away, and that spec ran as intended after.
I know this is a simple issue, but if you have hundreds upon hundreds of spec files, you may not be constantly looking at the file names.
In RSpec I could create helper modules in /spec/support/...
module MyHelpers
def help1
puts "hi"
end
end
and include it in every spec like this:
RSpec.configure do |config|
config.include(MyHelpers)
end
and use it in my tests like this:
describe User do
it "does something" do
help1
end
end
How can I include a module into all MiniTest tests without repeating myself in every test?
From the Minitest README:
=== How to share code across test classes?
Use a module. That's exactly what they're for:
module UsefulStuff
def useful_method
# ...
end
end
describe Blah do
include UsefulStuff
def test_whatever
# useful_method available here
end
end
Just define the module in a file and use require to pull it in. For example, if 'UsefulStuff' is defined in test/support/useful_stuff.rb, you might have require 'support/useful_stuff' in either your individual test file.
UPDATE:
To clarify, in your existing test/test_helper.rb file or in a new test/test_helper.rb file you create, include the following:
Dir[Rails.root.join("test/support/**/*.rb")].each { |f| require f }
which will require all files in the test/support subdirectory.
Then, in each of your individual test files just add
require 'test_helper'
This is exactly analogous to RSpec, where you have a require 'spec_helper' line at the top of each spec file.
minitest does not provide a way to include or extend a module into every test class in the same way RSpec does.
Your best bet is going to be to re-open the test case class (differs, depending on the minitest version you're using) and include whatever modules you want there. You probably want to do this in either your test_helper or in a dedicated file that lets everyone else know you're monkey-patching minitest. Here are some examples:
For minitest ~> 4 (what you get with the Ruby Standard Library)
module MiniTest
class Unit
class TestCase
include MyHelpers
end
end
end
For minitest 5+
module Minitest
class Test
include MyHelperz
end
end
You can then use the included methods in your test:
class MyTest < Minitest::Test # or MiniTest::Unit::TestCase
def test_something
help1
# ...snip...
end
end
Hope this answers your question!
One thing I will do is create my own Test class inheriting from Minitest::Test. This allows me to do any sort of configuration on my base test class and keeping it isolated to my own project1.
# test_helper.rb
include 'helpers/my_useful_module'
module MyGem
class Test < Minitest::Test
include MyUsefulModule
end
end
# my_test.rb
include 'test_helper'
module MyGem
MyTest < Test
end
end
1 This is most likely unneeded, but I like keeping all my gem code isolated.
Using rails and rspec it's easy to have rspec generate the necessary files for me when I'm using the rails generate command with models/views/controllers. But now I want to write specs for a module I wrote. The module is in /lib/my_module.rb so I created a spec in /spec/lib/my_module_spec.rb
The problem I'm having is that when I try to do rspec spec/ the file my_module_spec.rb is run but the reference to my module in lib/my_module.rb can't be found. What's the right way to do this?
Just FYI the my_module_spec.rb file does have require 'spec_helper' in it already
require 'spec_helper'
describe "my_module" do
it "first test"
result = MyModule.some_method # fails here because it can't find MyModule
end
end
You could try including the module and maybe wrapping it in an object
require 'spec_helper'
#EDIT according to
# http://stackoverflow.com/users/483040/jaydel
require "#{Rails.root}/lib/my_module.rb"
describe MyModule do
let(:wrapper){
class MyModuleWrapper
include MyModule
end
MyModuleWrapper.new
}
it "#some_method" do
wrapper.some_method.should == "something"
end
end
Does your module contain class methods or instance methods? Remember that only class methods will be available via
MyModule.some_method
meaning that some_method is defined as
def self.some_method
...
end
If your module contains instance methods, then use Jasper's solution above. Hope that clarifies.
Put the following in your config/application.rb file:
config.autoload_paths += %W(#{Rails.root}/lib)
I was just wrestling with the same problem, and the above worked for me. There's not really any reason you should have to jump through hoops to be able to access your lib/ files from RSpec and write tests for them.