I am trying to setup the unit testing with Factory Girl and Rspec for my Sinatra application.
Gem file:
group :test do
gem "rack-test"
gem "fuubar"
gem "factory_girl"
gem "yard"
end
spec/factories/vserver.rb
require 'factory_girl'
FactoryGirl.define do
factory :vserver do
first_name "John"
last_name "Doe"
end
end
spec/spec_helper.rb
require File.join(File.dirname(__FILE__), "..", "app.rb")
%w{
rubygems
sinatra
dm-core
rack/test
uuid
factory_girl
rspec
pp
spec/factories/vserver
}.each { |r| require r }
set :environment, :test
# RSpec without Rails
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
spec/app_spec.rb
require './spec_helper.rb'
require 'factory_girl'
describe "Cdot" do
include Rack::Test::Methods
def app
StorageApi
end
it 'vserver' do
FactoryGirl.build(:vserver)
end
end
Issue: When I run the rspec file using the command: rspec app_spec.rb, I get the below error.
NameError: uninitialized constant Vserver
Help is much appreciated.
the code: factory :vserver do assumes that you have a class called Vserver that you are instantiating.
If you have such a class, then you need to include it in your spec.
If you don't have such a class, then you either need to rename the factory, or tell it what class it should be instantiating instead.
Related
I am using Rspec with selenium-webdriver gem to test a web app. And I wanted to unclude factories in my tests to emulate users and not to create a user manually each time.
So, I made gem install factory_girl, added required lined in my spec_helper, created a factory and included some lines in my spec file. And when running the test I get an error
Failure/Error: FactoryGirl.build(:user)
NameError:
uninitialized constant User
Here is my spec_helper.rb
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
My factories.rb file:
FactoryGirl.define do
factory :user do
name "testuser"
password "freestyle"
inventory true
end
end
And my test_spec file:
require "json"
require "selenium-webdriver"
require "rspec"
require "factory_girl"
FactoryGirl.find_definitions
include RSpec::Expectations
describe "MallSpec" do
before(:all) do
FactoryGirl.build(:user)
#driver = Selenium::WebDriver.for :firefox
#base_url = "http://localhost:9000/"
#accept_next_alert = true
#driver.manage.timeouts.implicit_wait = 30
#driver.manage.window.resize_to(1301, 744)
#verification_errors = []
end
My spec_file is in the root dir of the project. my factories.rb file is in /spec dir as well as the test_spec.rb itself.
Can anyone help me with this issue or point what i am doing wrong?
If you don't actually have a User class but you want to use FactoryGirl to generate the attributes, you can override the class:
require "ostruct"
FactoryGirl.define do
factory :user, class: OpenStruct do
name "testuser"
password "freestyle"
inventory true
# This isn't necessary, but it will prevent FactoryGirl from trying
# to call #save on the built instance.
to_create {}
end
end
You can then use attributes_for if you just want a Hash, or create if you want an object that responds to methods like name.
You can use a library like Hashie::Mash if you want to generate JSON for use in your API:
factory :user, class: Hashie::Mash do
# ...
end
# In your tests:
user_json = create(:user).to_json
And when running the test I get an error Failure/Error:
FactoryGirl.build(:user) NameError: uninitialized constant User
Your User class has to be defined. The following is a test with no User class defined:
require 'factory_girl'
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
FactoryGirl.define do
factory :user do
name 'Alice'
age 10
end
end
describe "MallSpec" do
let(:test_user) { FactoryGirl.build(:user) }
describe "user's name" do
it "equals 'Alice'" do
expect(test_user.name).to eq('Alice')
end
end
end
--output:--
$ rspec 1.rb
F
Failures:
1) MallSpec user's name equals 'Alice'
Failure/Error: let(:user) { FactoryGirl.build(:user) }
NameError:
uninitialized constant User
...
Adding a definition for the User class:
require 'factory_girl'
#====NEW CODE=====
class User
attr_accessor :name, :age
end
#=================
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
FactoryGirl.define do
factory :user do
name 'Alice'
age 10
end
end
describe "MallSpec" do
let(:test_user) { FactoryGirl.build(:user) }
describe "user's name" do
it "equals 'Alice'" do
expect(test_user.name).to eq('Alice')
end
end
end
--output:--
$ rspec 1.rb
.
Finished in 0.0024 seconds (files took 0.35197 seconds to load)
1 example, 0 failures
I expect that the factory() method here:
factory :user do
name 'Alice'
age 10
end
...does something like this:
def factory(model_name)
target_class = constant_get(model_name.capitalize)
...in order to construct a real instance of the User class. In other words, factory_girl constructs instances of classes that already exist in your app--factory_girl does not mock a class.
I'm write some specs to cover my HTML helpers
describe Sinatra::Helpers::HTML do
describe 'tag' do
it 'should retun selfclosed tag' do
Helpers.tag(:br, {}, true).should == '<br />'
end
it 'should have valid attributes' do
Helpers.tag(:div, :class => 'test').should include("class='test'")
end
it 'should contain value returned from block' do
tag = Helpers.tag(:div) { 'Block value' }
tag.should include('Block value')
end
end
describe 'stylesheet_tag' do
it 'should return link tag' do
Helpers.stylesheet_tag('test').should include('link')
end
it 'should contain path to asset' do
end
end
end
When I run it on local machine all is good, everything pass. But after pushing to GitHub repo Travis fails and write that Object::Sinatra is uninitialized (link) and I haven't idea why.
spec_helper.rb looks:
ENV['RACK_ENV'] = "test"
require 'simplecov'
SimpleCov.start
require File.join(File.dirname(__FILE__), '..', 'boot')
require 'rspec'
require 'capybara/rspec'
require 'rack/test'
require 'factory_girl'
FactoryGirl.find_definitions
Capybara.app = Orodruin.rack
RSpec.configure do |config|
config.include Rack::Test::Methods
config.after(:each) do
MongoMapper.database.collections.each do |collection|
collection.remove unless collection.name.match(/^system\./)
end
end
end
class Helpers
extend(*Sinatra::Base.included_modules.map(&:to_s).grep(/Helpers/).map(&:constantize))
end
because http://travis-ci.org/#!/orodruin/orodruin/jobs/2248831/L73 isn't using bundle exec.
the "bundle exec rake" line above it didn't seem to do anything.
you will need to prefix that line with bundle exec.
I don't see that line in your code, but it could be hard coded in one of your gems or in the Travis service.
The real problem is that the sinatra gem isn't found when Travis is running the specs. This is because travis is using an RVM gemset, and you are probably using the "global" gemset.
The result is ruby -s rspec ... isn't being ran in the gem bundle environment and isn't loading Sinatra.
I've forgot to add require 'spec_helper' on top of my specfile.
Ok, I'm baffled. I'm trying to use shoulda with Test::Unit under Rails 3.1, having previously done so successfully with Rails 2.3.11.
I have the following in my Gemfile:
group :test do
gem 'shoulda'
end
(and I've run bundle install - bundle show shoulda shows c:/Ruby192/lib/ruby/gems/1.9.1/gems/shoulda-2.11.3)
I have the following test_helper.rb
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'shoulda'
class ActiveSupport::TestCase
end
and the following user_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
should validate_presence_of :email
should validate_format_of(:email).with("user+throwaway#subdom.example.com").with_message(/valid email address/)
should validate_presence_of(:encrypted_password)
should validate_confirmation_of :password
end
But when I do ruby -Itest test\unit\user_test.rb, I get the following error:
test/unit/user_test.rb:4:in `<class:UserTest>': undefined method `validate_presence_of' for UserTest:Class (NoMethodError)
What have I failed to set up properly?
Solved it. You need:
require 'shoulda/rails'
in test_helper.rb (not `require 'shoulda'); and the test case needs to be:
class Usertest < ActiveRecord::TestCase
(not < ActiveSupport::TestCase).
I'd tried both of those individually, but not together...
I have a very simple Sinatra app which I'm having trouble testing.
Basically, every single request test returns a 404 when I know from testing in the browser that the request works fine. Any ideas as to what the problem might be?
test_helper.rb:
ENV["RACK_ENV"] = 'test'
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
require 'app'
Sinatra::Synchrony.patch_tests!
class Test::Unit::TestCase
include Rack::Test::Methods
end
app_test.rb
require 'test_helper'
class AppTest < Test::Unit::TestCase
def app
#app ||= Sinatra::Application
end
def test_it_says_hello
get "/"
assert_equal 200, last_response.status
end
end
app.rb
$: << 'config'
require "rubygems" require "bundler"
ENV["RACK_ENV"] ||= "development"
Bundler.require(:default, ENV["RACK_ENV"].to_sym)
require ENV["RACK_ENV"]
class App < Sinatra::Base register Sinatra::Synchrony
get '/' do
status 200
'hello, I\'m bat shit crazy and ready to rock'
end
end
Gemfile
source :rubygems
gem 'daemons'
gem 'sinatra'
gem 'sinatra-synchrony', :require => 'sinatra/synchrony'
gem 'resque'
gem 'thin'
group :test do
gem 'rack-test', :require => "rack/test"
gem 'test-unit', :require => "test/unit"
end
Why can I not get this normally very simple thing working?
I had quite the same problem with only HTTP-404 coming in return.
I solved it with giving another return in the "app" function.
class IndexClassTest < Test::Unit::TestCase
def app
#app = Foxydeal #appname NOT Sinatra::Application
end
...
Also
Sinatra::Synchrony.patch_tests!
seems to be obsolete.
Under your app_test.rb do this instead of what you have now:
def app
#app ||= App.new
end
This will work with your your class style like you had it in the beginning, no need to switch to the non-class/modular style.
It may seem logical, but are your routes configured correctly? If a route isn't correctly configured, it'll throw 404 errors left and right.
Figured it out.
app.rb
$: << 'config'
require "rubygems" require "bundler"
ENV["RACK_ENV"] ||= "development" Bundler.require(:default,
ENV["RACK_ENV"].to_sym) require ENV["RACK_ENV"]
class App < Sinatra::Base
register Sinatra::Synchrony
end
get '/' do
status 200
'hello, I\'m bat shit crazy and ready to rock'
end
You may simply do this:
class AppTest < Test::Unit::TestCase
def app
Sinatra::Application
end
You can get a solid understanding of sinatra tests by reading Learning From the Masters: Sinatra Internals and Rack::Test
I'm trying to use Webrat in a standalone script to automate some web browsing. How do I get the assert_contain method to work?
require 'rubygems'
require 'webrat'
include Webrat::Methods
include Webrat::Matchers
Webrat.configure do |config|
config.mode = :mechanize
end
visit 'http://gmail.com'
assert_contain 'Welcome to Gmail'
I get this error
/usr/lib/ruby/gems/1.8/gems/webrat-0.6.0/lib/webrat/core/matchers/have_content.rb:57:in 'assert_contain': undefined method assert' for #<Object:0xb7e01958> (NoMethodError)
assert_contain and other assertions are methods of test/unit, try to require it and use webrat from inside a test method:
require 'test/unit'
class TC_MyTest < Test::Unit::TestCase
def test_fail
assert(false, 'Assertion was false.')
end
end
anyway i haven't tested it but I have a working spec_helper for rspec if this can interest you:
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
require 'spec/rails'
require "webrat"
Webrat.configure do |config|
config.mode = :rails
end
module Spec::Rails::Example
class IntegrationExampleGroup < ActionController::IntegrationTest
def initialize(defined_description, options={}, &implementation)
defined_description.instance_eval do
def to_s
self
end
end
super(defined_description)
end
Spec::Example::ExampleGroupFactory.register(:integration, self)
end
end
plus a spec:
# remember to require the spec helper
describe "Your Context" do
it "should GET /url" do
visit "/url"
body.should =~ /some text/
end
end
give it a try I found it very useful (more than cucumber and the other vegetables around) when there is no need to Text specs (features) instead of Code specs, that I like the most.
ps you need the rspec gem and it installs the 'spec' command to execute your specs.