My problem is I'm creating a wrapper to deal with a connection to an external server (GeoNetwork) and treat its response.
While I had my request in my Search Controller, it was working fine. Then I tried to follow this solution for the wrapper:
http://code.tutsplus.com/articles/writing-an-api-wrapper-in-ruby-with-tdd--net-23875
But now, I'm having an error on webmock that I can't figure out why.
../lib/wrapper/api.rb
module Wrapper
class Api
class << self
attr_accessor :base_uri
end
include HTTP
#base_uri = 'http://boldo.caiena.net:8080/geonetwork/srv/eng/'
builder_for_summary = Nokogiri::XML::Builder.new do |xml|
xml['csw'].GetRecords('xmlns:csw' => 'http://www.opengis.net/cat/csw/2.0.2',
'service' => 'CSW',
'version' => '2.0.2',
'resultType' => 'results',
# metadata records start at position 1
'startPosition' => '1',
'maxRecords' => '10') do
xml['csw'].Query('typeNames' => 'gmd:MD_Metadata') {
xml['csw'].Constraint('version' => '1.1.0'){
xml.Filter('xmlns' => 'http://www.opengis.net/ogc',
'xmlns:gml' => 'http://www.opengis.net/gml'){
xml.PropertyIsLike('wildCard' => '',
'singleChar' => '_'){
xml.PropertyName 'any'
xml.Literal '' #params[:search_field]
}
}
}
}
end
end
response = HTTP.post("#{#base_uri}csw", body: builder_for_summary.to_xml)
.with_headers(content_type: "application/xml")
.response
end
end
../spec/lib/api_spec.rb
require 'spec_helper'
describe Wrapper::Api do
it 'should work' do
expect('Yay!').to be_an_instance_of String
end
describe 'default attributes' do
it 'should include http methods' do
expect(Wrapper::Api).to include HTTP
end
it 'should have the base url set to the GeoNetwork API endpoint' do
expect(Wrapper::Api.base_uri).to eq('http://boldo.caiena.net:8080/geonetwork/srv/eng/')
end
end
describe 'request' do
it 'makes a request to GeoNetwork' do
WebMock.should have_requested(:post, "#{Wrapper::Api.base_uri}csw")
end
end
end
../spec/spec_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require_relative '../config/environment'
require_relative '../lib/wrapper'
require 'rspec/rails'
require 'rspec/autorun'
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
RSpec.configure do |config|
config.before(:each) do
support_path = 'spec/support/fixtures/'
url = 'http://boldo.caiena.net:8080/geonetwork/srv/eng/'
canned_request = File.read "#{support_path}request_all_metadata.xml"
canned_response = File.read "#{support_path}all_metadata_results.xml"
stub_request(:post, "#{url}csw")
.with(header:'application/xml')
.to_return(body: canned_response)
end
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
# Enabling FactoryGirl methods with ease
config.include FactoryGirl::Syntax::Methods
config.include Capybara::DSL
end
The error I'm getting is:
/Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/webmock-1.17.4/lib/webmock/http_lib_adapters/http_gem_adapter.rb:125:in `halt': Real HTTP connections are disabled. Unregistered request: POST http://boldo.caiena.net:8080/geonetwork/srv/eng/csw with body '<?xml version="1.0"?> (WebMock::NetConnectNotAllowedError)
<csw:GetRecords xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" service="CSW" version="2.0.2" resultType="results" startPosition="1" maxRecords="10">
<csw:Query typeNames="gmd:MD_Metadata">
<csw:Constraint version="1.1.0">
<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
<PropertyIsLike wildCard="" singleChar="_">
<PropertyName>any</PropertyName>
<Literal/>
</PropertyIsLike>
</Filter>
</csw:Constraint>
</csw:Query>
</csw:GetRecords>
' with headers {'Host'=>'boldo.caiena.net', 'User-Agent'=>'RubyHTTPGem/0.5.0'}
You can stub this request with the following snippet:
stub_request(:post, "http://boldo.caiena.net:8080/geonetwork/srv/eng/csw").
with(:body => "<?xml version=\"1.0\"?>\n<csw:GetRecords xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" service=\"CSW\" version=\"2.0.2\" resultType=\"results\" startPosition=\"1\" maxRecords=\"10\">\n <csw:Query typeNames=\"gmd:MD_Metadata\">\n <csw:Constraint version=\"1.1.0\">\n <Filter xmlns=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\">\n <PropertyIsLike wildCard=\"\" singleChar=\"_\">\n <PropertyName>any</PropertyName>\n <Literal/>\n </PropertyIsLike>\n </Filter>\n </csw:Constraint>\n </csw:Query>\n</csw:GetRecords>\n",
:headers => {'Host'=>'boldo.caiena.net', 'User-Agent'=>'RubyHTTPGem/0.5.0'}).
to_return(:status => 200, :body => "", :headers => {})
============================================================
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/webmock-1.17.4/lib/webmock/http_lib_adapters/http_gem_adapter.rb:76:in `exec'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/webmock-1.17.4/lib/webmock/http_lib_adapters/http_gem_adapter.rb:146:in `perform'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/http-0.5.0/lib/http/client.rb:58:in `request'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/http-0.5.0/lib/http/chainable.rb:50:in `request'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/http-0.5.0/lib/http/chainable.rb:15:in `post'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/lib/wrapper/api.rb:34:in `<class:Api>'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/lib/wrapper/api.rb:2:in `<module:Wrapper>'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/lib/wrapper/api.rb:1:in `<top (required)>'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:229:in `require'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:229:in `block in require'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:214:in `load_dependency'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/activesupport-4.0.3/lib/active_support/dependencies.rb:229:in `require'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/lib/wrapper.rb:4:in `block in <top (required)>'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/lib/wrapper.rb:3:in `each'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/lib/wrapper.rb:3:in `<top (required)>'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/spec/spec_helper.rb:5:in `require_relative'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/spec/spec_helper.rb:5:in `<top (required)>'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/spec/controllers/search_controller_spec.rb:1:in `require'
from /Users/thiagoalves/Workspace/copernico-ide/copernico/spec/controllers/search_controller_spec.rb:1:in `<top (required)>'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `load'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `block in load_spec_files'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `each'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/configuration.rb:896:in `load_spec_files'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/command_line.rb:22:in `run'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/runner.rb:80:in `run'
from /Users/thiagoalves/.rvm/gems/ruby-2.1.0#copernico/gems/rspec-core-2.14.8/lib/rspec/core/runner.rb:17:in `block in autorun'
Related
I am trying to use Faker in FactoryBot in my Rails API tests.
The issue I am having that I keep getting this error:
KeyError:
Trait not registered: "first_name"
So far as I can tell I have configured everything right, based on Faker'd docs at least. So far as I can tell I have two actual traits, valid_user and invalid_user that I set like so...
let(:valid_attributes) { FactoryBot.attributes_for :api_v1_user, :valid_user }
let(:invalid_attributes) { FactoryBot.attributes_for :api_v1_user, :invalid_user }
Which are linked to the :api_v1_user factory.
What have I missed or done wrong?
Full Error:
8) /api/v1/users PATCH /update with invalid parameters renders a JSON response with errors for the api/v1_user
Failure/Error: let(:invalid_attributes) { FactoryBot.attributes_for(:api_v1_user, :invalid_user) }
KeyError:
Trait not registered: "first_name"
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/activesupport-6.0.2.2/lib/active_support/hash_with_indifferent_access.rb:191:in `fetch'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/activesupport-6.0.2.2/lib/active_support/hash_with_indifferent_access.rb:191:in `fetch'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/registry.rb:23:in `find'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/decorator.rb:10:in `method_missing'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/internal.rb:49:in `trait_by_name'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:114:in `trait_by_name'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:106:in `block in base_traits'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:106:in `map'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:106:in `base_traits'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:51:in `block in compile'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:50:in `compile'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:130:in `aggregate_from_traits_and_self'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:34:in `to_create'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/trait.rb:17:in `to_create'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:135:in `map'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:135:in `aggregate_from_traits_and_self'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition.rb:34:in `to_create'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/definition_hierarchy.rb:16:in `build_from_definition'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/factory.rb:125:in `build_hierarchy'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/factory.rb:88:in `compile'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/factory.rb:32:in `run'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/factory_runner.rb:29:in `block in run'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/activesupport-6.0.2.2/lib/active_support/notifications.rb:182:in `instrument'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/factory_runner.rb:28:in `run'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/factory_bot-5.1.2/lib/factory_bot/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
# ./spec/requests/api/v1/users_spec.rb:6:in `block (2 levels) in <top (required)>'
# ./spec/requests/api/v1/users_spec.rb:92:in `block (4 levels) in <top (required)>'
# ./spec/rails_helper.rb:19:in `block (3 levels) in <top (required)>'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/database_cleaner-1.8.4/lib/database_cleaner/generic/base.rb:16:in `cleaning'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:87:in `block (2 levels) in cleaning'
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/database_cleaner-1.8.4/lib/database_cleaner/configuration.rb:88:in `cleaning'
# ./spec/rails_helper.rb:18:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# KeyError:
# key not found: "first_name"
# /home/etherk1ll/.rvm/gems/ruby-2.7.0/gems/activesupport-6.0.2.2/lib/active_support/hash_with_indifferent_access.rb:191:in `fetch'
spec/factories/api/v1/users.rb
require 'faker'
FactoryBot.define do
factory :api_v1_user, class: 'Api::V1::User' do
trait :valid_user do
first_name { Faker::Name.first_name }
second_name { Faker::Name.second_name }
username { Faker::Internet.username }
email { Faker::Internet.safe_email }
password { Faker::Internet.password(min_length: 8) }
end
trait :invalid_user do
first_name nil
end
end
end
rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
RSpec.configure do |config|
config.use_transactional_fixtures = false
DatabaseCleaner.strategy = :truncation
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
config.before(:all) do
DatabaseCleaner.start
end
config.after(:all) do
DatabaseCleaner.clean
end
end
users_spec.rb
Truncated
RSpec.describe "/api/v1/users", type: :request do
let(:valid_attributes) { FactoryBot.attributes_for :api_v1_user, :valid_user }
let(:invalid_attributes) { FactoryBot.attributes_for :api_v1_user, :invalid_user }
let(:valid_headers) {
{}
}
describe "PATCH /update" do
context "with invalid parameters" do
it "renders a JSON response with errors for the api/v1_user" do
user = Api::V1::User.create! valid_attributes
patch api_v1_user_url(user),
params: { api_v1_user: invalid_attributes }, headers: valid_headers, as: :json
expect(response).to have_http_status(:unprocessable_entity)
expect(response.content_type).to eq("application/json")
end
end
end
end
Try wrapping the nil in brackets. FactoryBot eliminated support for static attributes in version 5, so if you're using a newer version, that'll be your problem. Brackets are now required.
trait :invalid_user do
first_name { nil }
end
To learn API by using Rails I'm reading this tutorial.
In a part of RSpec test there is a method like this:
spec/support/authentication_helper.rb
module AuthenticationHelper
def sign_in(user)
header('Authorization', "Token token=\"#{user.authentication_token}\", email=\"#{user.email}\"")
end
def create_and_sign_in_user
user = FactoryGirl.create(:user)
sign_in(user)
user
end
alias_method :create_and_sign_in_another_user, :create_and_sign_in_user
end
RSpec.configure do |config|
config.include AuthenticationHelper, type: :api
end
And the test failed by undefined method `header'.
Where is this header method defined?
This is the whole source code of this tutorial.
https://github.com/vasilakisfil/rails_tutorial_api/
spec/apis/users_spec.rb
require 'rails_helper'
describe Api::V1::UsersController, type: :api do
context :show do
before do
create_and_sign_in_user
#user = FactoryGirl.create(:user)
get api_v1_user_path(#user.id), format: :json
end
it 'returns the correct status' do
expect(last_response.status).to eql(200)
end
it 'returns the data in the body' do
body = HashWithIndifferentAccess.new(MultiJson.load(last_response.body))
expect(body[:user][:name]).to eql(#user.name)
expect(body[:user][:updated_at]).to eql(#user.updated_at.iso8601)
end
end
end
StackTrace
1) Api::V1::UsersController show returns the correct status
Failure/Error: create_and_sign_in_user
NameError:
undefined local variable or method `request' for #<RSpec::ExampleGroups::ApiV1UsersController::Show:0x007fcbfec91d60>
# ./spec/support/authentication_helper.rb:4:in `sign_in'
# ./spec/support/authentication_helper.rb:9:in `create_and_sign_in_user'
# ./spec/apis/user_spec.rb:6:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:39:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:38:in `block (2 levels) in <top (required)>'
# -e:1:in `<main>'
2) Api::V1::UsersController show returns the data in the body
Failure/Error: create_and_sign_in_user
NameError:
undefined local variable or method `request' for #<RSpec::ExampleGroups::ApiV1UsersController::Show:0x007fcbfb7cfa28>
# ./spec/support/authentication_helper.rb:4:in `sign_in'
# ./spec/support/authentication_helper.rb:9:in `create_and_sign_in_user'
# ./spec/apis/user_spec.rb:6:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:39:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:38:in `block (2 levels) in <top (required)>'
# -e:1:in `<main>'
I had to add api_helper.rb to use the methods.
module ApiHelper
include Rack::Test::Methods
def app
Rails.application
end
end
RSpec.configure do |config|
config.include ApiHelper, type: :api #apply to all spec for apis folder
config.include Rails.application.routes.url_helpers, type: :api
end
Here is source code in Github.
https://github.com/vasilakisfil/rails_tutorial_api/blob/008af67e88897a5bcde714ce13d39a26ec70fba7/spec/support/api_helper.rb
In spec/support/auth_helpers.rb, you can try something like this
module AuthHelpers
def authenticate_with_user(user)
request.headers['Authorization'] = "Token token=#{user.token}, email=#{user.email}"
end
def clear_authentication_token
request.headers['Authorization'] = nil
end
end
In Rspec's spec/rails_helper.rb
Rspec.configure do |config|
config.include AuthHelpers, file_path: /spec\/apis/
end
An example test in spec/apis/users_controller_spec.rb:
require 'rails_helper'
describe Api::V1::UsersController, type: :controller do
let(:user) { create(:user) }
context 'signed in' do
before do
authenticate_with_user user
end
it 'does something' # tests here
end
end
Hope it helps!
Edit: Note the type: :controller is important
## app/models/armor_type.rb
class ArmorType < ActiveRecord::Base
validates :name, presence: true
...
end
## spec/models/armor_type_spec.rb
require 'rails_helper'
RSpec.describe ArmorType, type: :model do
it "has a valid name" do
armor_type = create(:armor_type)
end
end
## spec/factories/armor_types.rb
FactoryGirl.define do
factory :armor_type do
name "cloth"
end
end
## spec/support/factory_girl.rb
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
## spec/rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'support/factory_girl'
require 'capybara/rspec'
## Gemfile
group :development, :test do
gem 'byebug'
gem 'rspec-rails'
gem 'factory_girl_rails'
end
I can't seem to get factory_girl to work properly. I created at testApp using a SQLite3 test database and it worked, however using my current application which uses a PostgreSQL test database I get the following error;
1) ArmorType has a valid name
Failure/Error: armor_type = create(:armor_type)
NoMethodError:
undefined method `save!' for #<ArmorType:0x000000071a8b58 #name="cloth">
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/configuration.rb:14:in `block in initialize'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/evaluation.rb:15:in `[]'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/evaluation.rb:15:in `create'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:9:in `tap'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:9:in `result'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/factory.rb:42:in `run'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/factory_runner.rb:23:in `block in run'
# ./.bundle/gems/activesupport-4.2.3/lib/active_support/notifications.rb:166:in `instrument'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/factory_runner.rb:22:in `run'
# ./.bundle/gems/factory_girl-4.5.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
# ./spec/models/armor_type_spec.rb:6:in `block (2 levels) in <top (required)>'
# .bundle/binstubs/rspec:16:in `load'
# .bundle/binstubs/rspec:16:in `<main>'
I've gone ahead and created another test app using a PostgreSQL test database and I get the same errors. Any help would be appreciated.
Cheers!
I had inadvertently created a file 'armor_type.rb" in the very early stages of testing, resulting in this error. It was not related to factory_girl, nor rspec.
newbiemistakes
I'm trying to use Rspec 1.3.1 for my rails application which is running on 2.3.8. I am able to 'stub' the models with stub_model method. But when I call mock_model, things go wrong and this is the stack trace I get
./spec/models/bucket_spec.rb:32: undefined method `mock_model' for Spec::Rails::Example::ModelExampleGroup::Subclass_2:Class (NoMethodError)
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/example/example_group_methods.rb:188:in `module_eval'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/example/example_group_methods.rb:188:in `subclass'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/example/example_group_methods.rb:55:in `describe'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/example/example_group_factory.rb:31:in `create_example_group'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/dsl/main.rb:28:in `describe'
from ./spec/models/bucket_test.rb:31
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/runner/example_group_runner.rb:15:in `load'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/runner/example_group_runner.rb:15:in `load_files'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/runner/example_group_runner.rb:14:in `each'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/runner/example_group_runner.rb:14:in `load_files'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/runner/options.rb:134:in `run_examples'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/lib/spec/runner/command_line.rb:9:in `run'
from /usr/local/lib/ruby/gems/1.8/gems/rspec-1.3.1/bin/spec:5
from /usr/local/bin/spec:19:in `load'
from /usr/local/bin/spec:19
The bucket_spec.rb file:
require 'spec_helper'
describe Bucket, "creation" do
before(:each) do
#bucket = stub_model(Bucket, :id => 1, :name => "Below Proficient", :color => "green", :min_range => 0, :max_range => 30, :class_group_id => 1).as_new_record
end
it "should be valid with all the attributes set to some randowm values" do
#bucket.should be_valid
end
it "should be valid without min_range" do
#bucket.min_range = nil
#bucket.should be_valid
end
it "should be valid without max_range" do
#bucket.max_range = nil
#bucket.should be_valid
end
it "should be valid without class_group_id" do
#bucket.class_group_id = nil
#bucket.should be_valid
end
it "should not be valid without color" do
#bucket.color = nil
#bucket.should_not be_valid
end
it "should not be valid without name" do
#bucket.name = nil
#bucket.should_not be_valid
end
end
describe Bucket, "saving" do
#bucket = mock_model(Bucket)
#bucket.should be_valid
end
The spec_helper.rb file:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'spec/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
#
#RSpec.configure do |config|
# # == Mock Framework
# #
# # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
# #
# # config.mock_with :mocha
# # config.mock_with :flexmock
# # config.mock_with :rr
# config.mock_with :rspec
#
# # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
#
# # If you're not using ActiveRecord, or you'd prefer not to run each of your
# # examples within a transaction, remove the following line or assign false
# # instead of true.
# config.use_transactional_fixtures = true
#end
Spec::Runner.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = true
end
The list of rspec gems
gem list rspec
*** LOCAL GEMS ***
rspec (1.3.1)
rspec-rails (1.3.3)
The list of rails gems
gem list rails
*** LOCAL GEMS ***
rails (2.3.8, 2.3.5)
Your call to mock_model is at the top level of your describe block which doesn't make sense
You can only do that inside a before(:each), an example (ie in the block passed to it) and places like that
I have one spec:
require 'spec_helper'
# hmm... I need to include it here because if I include it inside describe block `method_missing` exception raises.
include Shoulda::ActionController::Matchers
describe CategoriesController do
include Devise::TestHelpers
render_views
context "new should render template :new" do
setup do
sign_in :user
get :new
end
should render_template(:new)
end
end
when I run rake spec I see this(but if i change context to it and move setup block contents to it block all works fine):
localhost:gallery rtest$ rake spec
(in /Users/rtest/Projects/gallery)
/Users/rtest/.rvm/rubies/ruby-1.9.2-p0/bin/ruby -S bundle exec /Users/rtest/.rvm/rubies/ruby-1.9.2-p0/bin/ruby -Ilib -Ispec "./spec/controllers/categories_controller_spec.rb" "./spec/controllers/photos_controller_spec.rb" "./spec/helpers/categories_helper_spec.rb" "./spec/helpers/photos_helper_spec.rb" "./spec/models/category_spec.rb"
***
Pending:
CategoriesHelper add some examples to (or delete) /Users/rtest/Projects/gallery/spec/helpers/categories_helper_spec.rb
# Not Yet Implemented
# ./spec/helpers/categories_helper_spec.rb:14
PhotosHelper add some examples to (or delete) /Users/rtest/Projects/gallery/spec/helpers/photos_helper_spec.rb
# Not Yet Implemented
# ./spec/helpers/photos_helper_spec.rb:14
Category add some examples to (or delete) /Users/rtest/Projects/gallery/spec/models/category_spec.rb
# Not Yet Implemented
# ./spec/models/category_spec.rb:4
Finished in 0.0006 seconds
3 examples, 0 failures, 3 pending
/Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/shoulda-2.11.3/lib/shoulda/action_controller/matchers/render_template_matcher.rb:41:in `renders_template?': undefined method `assert_template' for #<Class:0x00000104839eb0> (NoMethodError)
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/shoulda-2.11.3/lib/shoulda/action_controller/matchers/render_template_matcher.rb:23:in `matches?'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-expectations-2.0.0.beta.20/lib/rspec/expectations/handler.rb:11:in `handle_matcher'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-expectations-2.0.0.beta.20/lib/rspec/expectations/extensions/kernel.rb:27:in `should'
from ./spec/controllers/categories_controller_spec.rb:17:in `block (2 levels) in <main>'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/example_group.rb:129:in `module_eval'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/example_group.rb:129:in `subclass'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/example_group.rb:116:in `describe'
from ./spec/controllers/categories_controller_spec.rb:11:in `block in <main>'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/example_group.rb:129:in `module_eval'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/example_group.rb:129:in `subclass'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/example_group.rb:116:in `describe'
from /Users/rtest/.rvm/gems/ruby-1.9.2-p0/gems/rspec-core-2.0.0.beta.20/lib/rspec/core/extensions/object.rb:7:in `describe'
from ./spec/controllers/categories_controller_spec.rb:6:in `<main>'
Loaded suite /Users/rtest/.rvm/gems/ruby-1.9.2-p0/bin/rake
Started
Finished in 0.003418 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Test run options: --seed 39993
My spec_helper.rb:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'shoulda'
require 'shoulda/rails'
require 'shoulda/integrations/rspec2'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, comment the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
end
I am using rails 3. rspec/shoulda/factory_girl are included to the application by this code in Gemfile:
group :test, :development do
gem 'autotest'
gem 'factory_girl'
gem "shoulda"
gem "rspec-rails", ">= 2.0.0.beta.20"
end
I'm pretty sure that error is because you haven't wrapped your shoulda assertion inside an it block like so:
it { should render_template(:new) }
This is required when using Shoulda with RSpec.
should render_template(:new) on it's own will work with Test::Unit.
If I'm not mistaken, I've used Shoulda and I think the syntax is
should_render_template(:new)
and not
should render_template(:new)
which explains the 0 tests,0 assertions...