how to test a gem's file - ruby-on-rails

I have a gem inside my Rails project, really simple, it translate an ip address to a real address (e.g. Gem.locate '127.0.0.1' returns { country: 'de' }
The code is like this
ip_locator/lib/service.rb
module IpLocator
class Service
include Singleton
attr_reader :db
def initialize
#db = MaxMindDB.new('db/GeoLite2-City.mmdb')
end
def locate(ip)
db.lookup ip
end
end
end
when I'm in the rails project, I can properly do this: IpLocator::Service.instance.locate '74.125.225.224' and get the information I need.
Now I'm trying add some tests to the gem (not in the rails project).
require 'spec_helper'
RSpec.describe IpLocator do
describe 'ip_locator' do
context 'when the data exists' do
let(:ip) { '74.125.225.224' }
subject do
IpLocator::Service.instance.locate ip
end
it 'return country data' do
expect(subject.found).to be_truthy
end
end
end
end
but when I run the test, I get
1) IpLocator ip_locator when the data exists return country data
Failure/Error: IpLocator::Service.instance.locate ip
NameError:
uninitialized constant IpLocator::Service
I already tried to change IpLocator::Service to Service, I tried require ip_locator inside the spec file (although it is already required inside spec_helper.rb). I'm pretty sure I'm doing something really stupid but not sure what exactly
Here is my spec_helper.rb
require 'bundler/setup'
Bundler.setup
require 'byebug'
require 'ip_locator'
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each { |file| require file }
RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = '.rspec_status'
# Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching!
config.expect_with :rspec do |c|
c.syntax = :expect
end
end
and I'm seeing the error:
NameError: uninitialized constant IpLocator::Service::Singleton
Did you mean? SignalException
then, if I try to require singleton as well in the spec_helper, I get
1) IpLocator::Service ip_locator when the data exists return country data
Failure/Error: #db = ::MaxMindDB.new('db/GeoLite2-City.mmdb')
NameError:
uninitialized constant MaxMindDB
I'm getting crazy

Related

How to configure Sorbet with rspec?

I have a simple test but the describe keyword is not working in Sorbet tests.
The error I'm receiving on these methods:
Method `describe` does not exist on `T.class_of(<root>)`7003
RSpec.describe(Model) do
describe 'my test' do
before(:each) do # .before error
user = FactoryBot.create(:user)
end
it 'can fill in all fields' do # .it errors
end
end
end
I think I need to tell Sorbet some how that this is called in the context of spec_helper.rbbut I'm not sure how to do that.
I've already installed this gem rspec-sorbet and ran
spec/spec_helper.rb
require 'rspec/sorbet'
To silence the errors, I ran this:
RSpec.describe(Model) do
T.bind(self, T.untyped)
# T.bind(self, RSpec) This does not work either
end

"Undefined method `build'" when using Rspec + FactoryBotRails

I'm trying this gem called FactoryBotRails. For some reason, when I try it on one of my models unit tests, the following error is thrown.
Failure/Error: my_model = build(:my_model)
NoMethodError:
undefined method `build' for #\<\RSpec::ExampleGroups::MyModel::ValidationTests:0x000055c553959958>
I don't know what I'm doing wrong, as long as I have followed several tutorials on the web, and did the same steps.
Added, in:
gemfile
gem 'factory_bot_rails', '~> 5.1.1'
app/spec/support/factory_bot.rb
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
spec/factories/my_models.rb
FactoryBot.define do
factory :my_model do
name { 'some name' }
code { 'some code' }
end
end
And used it like:
my_model = build(:my_model)
What is wrong with my configuration?
The issue might not be what you're calling, but where you're calling it. my_model = build(:my_model) is not syntax you want to use while writing specs, and the error message looks maybe you're calling it from outside of a spec? Because if you're calling it from within a spec, the error should be something along the lines of ArgumentError: Factory not registered: my_model. The spec itself should look like this:
# spec/models/my_model_spec.rb
require 'rails_helper'
describe MyModel do
let(:my_model) { build :my_model }
it { expect(my_model).to be_valid }
end
I would also specify the model name in your factory declaration (i.e., factory :my_model, class: 'MyModel' do). If you want to play with your factories, you can start up a test console:
# start rails console in 'test' environment
rails console test
my_model = FactoryBot.build :my_model
Note that you will need to use FactoryBot.build instead of build in your test console.
If this doesn't resolve your issue, please update your post with the contents of the spec you're trying to run, how you're trying to run it, and expand your definition of your spec/rails_helper.rb file. Since you're new to RSpec, I also suggest checking out http://www.betterspecs.org/ for best practices.
Probably you're missing to setup shortcuts for FactoryGirl by including its methods in your rails_helper:
RSpec.configure do |config|
# ...
config.include FactoryGirl::Syntax::Methods
end
The syntax for creation of factorybot is:
FactoryBot.create :my_model
Pass arguments hash if you need something different:
FactoryBot.create :my_model, name: "John Doe"
For multiple (e.g. 10 my_models):
FactoryBot.create_list :my_model, 10

uninitialized constant (Name error) with rails-rspec

i have created a spec/support/features directory. Added a file named sign_in.rb
with a module
module Features
def sign_in
end
end
but when i added this to spec/rails_helper.rb file as
....
config.include Features, type: :feature
end
then while running rake its showing uninitialized constant Features (Name error). I really did not understand this. Asking for help.
all i needed to add following line to rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

how do I extend LOAD_PATH for MiniTest?

[Aside: I am slowly answering my own question in "a concise recipe for installing, configuring and running minitest under autotest or Guard"]
My environment: Ruby 2.0. Padrino 0.10.7. Minitest 2.6.2. RackTest 0.6.2.
Short form: What is the best way to extend $LOAD_PATH to include my test directory so I can simply require 'test_helper' in my test files?
Long form:
Here's a sample test file. Note the require_relative "../../../test_helper" -- this requires keeping track of the test file relative to the test_helper.
# file: test/models/api/v0/index_test.rb
require_relative '../../../test_helper'
describe 'nobody home' do
it 'fetch fails' do
get "/api/v0/a_uri_that_does_not_exist"
last_response.status.must_equal 404
end
end
Here's the test helper:
# file: test/test_helper.rb
PADRINO_ENV = 'test' unless defined?(PADRINO_ENV)
require File.expand_path('../../config/boot', __FILE__)
class MiniTest::Unit::TestCase
include Rack::Test::Methods
def app
Demo.tap { |app| }
end
end
And finally, the rakefile that drives it (generated by padrino, invoked via padrino rake test):
# file: test/test.rake
require 'rake/testtask'
test_tasks = Dir['test/*/'].map { |d| File.basename(d) }
$stderr.puts("=== test_tasks = #{test_tasks}")
test_tasks.each do |folder|
Rake::TestTask.new("test:#{folder}") do |test|
test.pattern = "test/#{folder}/**/*_test.rb"
test.verbose = true
end
end
desc "Run application test suite"
task 'test' => test_tasks.map { |f| "test:#{f}" }
So: what would it take to replace the brittle require_relative '../../../test_helper' with a dependable and easily remembered require 'test_helper'?
you need to add libs:
Rake::TestTask.new("test:#{folder}") do |test|
test.pattern = "test/#{folder}/**/*_test.rb"
test.verbose = true
test.libs << 'test' # <-- this
end
Or if you invoke directly it with ruby:
$ ruby -Itest test/test_file.rb

RSpec: undefined local variable or method `activate_authlogic'

My _spec file includes the code below, but my test fails with:
NameError in 'MembershipsController should allow you to save updates to the notes'
undefined local variable or method `activate_authlogic' for #<Spec::Rails::Example::ControllerExampleGroup::Subclass_1:0x107cee930>
I don't understand why activate_authlogic is undefined in this case. I've used this line in TestUnit many times, and the RSpec examples I've read all seem to say that this should work. NOTE: I've also tried adding require 'authlogic' to the top of the _spec file, but it produces an identical error message.
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require 'ruby-debug'
describe MembershipsController do
before(:each) do
activate_authlogic
#admin = Factory(:admin, :email => "admin#example.com")
UserSession.create(#admin)
end
...
end
Apparently a misunderstanding on my part. Instead of require 'authlogic'
I needed require 'authlogic/test_case'

Resources