Best way to fill development db in rails
Faker is also a good solution.
Here's how my lib/tasks/sample_data.rake
looks like. I run it with rake db:populate
.
Creates 50 entries with random info.
require 'faker'
namespace :db do
desc "Fill database with sample data"
task :populate => :environment do
Rake::Task['db:reset'].invoke
50.times do |n|
name = Faker::Company.name
year = 1900+rand(111)
rating = 1+rand(10)
watched = (1 == rand(2) ? true : false)
imdb_id = rand(1000000)
Movie.create!(:name => name,
:year => year,
:rating => rating,
:watched => watched,
:imdb_id => imdb_id)
end
end
end
shoulda macros with rspec2 beta 5 and rails3 beta2
Using RSpec 2.0.0.beta.19
# Gemfile
group :test do
gem "rspec", ">= 2.0.0.beta.19"
gem "rspec-rails", ">= 2.0.0.beta.17"
gem "shoulda"
end
# spec/spec_helper.rb
require 'rspec/rails'
require 'shoulda/integrations/rspec2' # Add this line
# In your specs....
it { should validate_presence_of(:name) }
Running rake spec
should now load and run specs including the RSpec 2 matchers.
Can an RSpec scenario example only have one assertion?
Your spec (= feature) only has one example (= scenario). That example has three expectations (= assertions). (You may want to edit your title and question to clarify the terminology.) When an expectation in an example fails, it raises an exception, and subsequent expectations never get a chance to run. That's just the way RSpec works. (It has nothing to do with whether you're using Capybara.) It's not a big deal if this behavior hides that one of the subsequent expectations would have failed; you'll find out as soon as you fix the first one and run the example again.
I recommend writing specs in the way that you have. Writing a separate spec for every expectation results in harder-to-read specs, because rspec's DSL was not designed to write specs efficiently or clearly with only one expectation per spec, and it results in more examples which makes your test suite slower.
Side note: Capybara's have_content
and have_text
are the same, so you only need one of those expectations.
Using RSpec to test for correct order of records in a model
In your code:
it "should have the right emails in the right order" do
Email.should == [@email_newest, @email]
end
You are setting the expectation that the Email
model should be equal to the array of emails.Email
is a class. You can't just expect the class to be equal to an array. All emails can be found by using all
method on class Email
.
You must set the expectation for two arrays to be equal.
it "should have the right emails in the right order" do
Email.order('created_at desc').all.should == [@email_newest, @email]
end
It should work like this.
Repeated test descriptions with RSpec for every user role
describe "GET 'index'" do
User::ROLES.each do |role|
context "for #{role} user" do
login_user(role)
it "has the right title" do
response.should have_selector("title", :content => "the title")
end
end
end
end
You can use ruby's iterators in your specs. Given your particular implementation you'll have to adjust the code, but this give you the right idea for DRY'ing out your specs.
Also you'll need to make the necessary adjustments so your specs read well.
When to use RSpec let()?
I always prefer let
to an instance variable for a couple of reasons:
- Instance variables spring into existence when referenced. This means that if you fat finger the spelling of the instance variable, a new one will be created and initialized to
nil
, which can lead to subtle bugs and false positives. Sincelet
creates a method, you'll get aNameError
when you misspell it, which I find preferable. It makes it easier to refactor specs, too. - A
before(:each)
hook will run before each example, even if the example doesn't use any of the instance variables defined in the hook. This isn't usually a big deal, but if the setup of the instance variable takes a long time, then you're wasting cycles. For the method defined bylet
, the initialization code only runs if the example calls it. - You can refactor from a local variable in an example directly into a let without changing the
referencing syntax in the example. If you refactor to an instance variable, you have to change
how you reference the object in the example (e.g. add an@
). - This is a bit subjective, but as Mike Lewis pointed out, I think it makes the spec easier to read. I like the organization of defining all my dependent objects with
let
and keeping myit
block nice and short.
A related link can be found here: http://www.betterspecs.org/#let
Related Topics
How to Reference a File from Inside of a Gem
Get SASS from Database (Compile Passed Data Instead of Reading from File)
Good Cucumber Examples in the Wild
Rake VS. Thor for Automation Scripts
"Uninitialized Constant" Error When Including a Module
How to Select Option in Drop Down Using Capybara
Count the Number of Lines in a File Without Reading Entire File into Memory
Ruby Check If Nil Before Calling Method
Creating Signature and Nonce for Oauth (Ruby)
Could Not Find a Valid Gem 'Rails' (>= 0) in Any Repository
Is Every Relavant Calculation Performed Every Time the Page Is Loaded
Rails, How to Render a View/Partial in a Model
How to Handle Constants in Ruby When Using Rails
Ruby - Using Class_Eval to Define Methods
How to Drop to the Irb Prompt from a Running Script