How to spec validates_uniqueness_of in Rspec? - ruby-on-rails-3

How does one do this? Couldn't find any examples online... (using rspec 2.5.0 & rails 3.0.5)

Found it in shoulda-matchers: http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/frames

before(:each) do
#attr = { :bar => "foobar" }
end
it "should reject duplicate bar" do
Foo.create!(#attr)
duplicate_bar = Foo.new(#attr)
duplicate_bar.should_not be_valid
end

Not sure if this exactly what you are looking for, but you could check the error messages after the save or update
#widget.save
#untested, but this should be close
#widget.errors.full_messages.include?("validation message you are looking for").should be true
But honestly, this is probably not something that you need to test in your unit tests (if that is where you are placing them). You are basically duplicating unit tests that Rails has already done for you. It would be more appropriate to check for the error message in the view in a cucumber integration test.

Related

Rails 5 Minitest ActionView::Template::Error: nil is not a valid asset source

I upgraded my Rails Application from 4.2 -> 5.0.0.1.
Other TESTS works fine (e.g. Model, Helper, Feature), but havinf trouble with my Controller Test.
I have read about Keyword arguments in controller & integration tests in Rails 5. So I changed the code structure as given below...
ActionView::Template::Error: nil is not a valid asset source
setup do
#logo = plogos(:main_logo)
end
test "should get edit" do
puts #logo.id // just to check...working fine
get :edit, params: {id: #logo.id}
assert_response :success
end
But I got new error with ActionView.
Is there anyone encountered and fixed the same issue, please help!
Thank you!
You may want to add some logtrace, probably it hints you where it went wrong.
May it be that the main_logo-fixture doesn't have an image? Since Rails 5 image_tag raises this error when given an nil-value, see also: Rails, "nil is not a valid asset source" for a particular image_tag (Carrierwave)
Besides that, typically the new scaffolded code would look as follows:
require 'test_helper'
class LogosControllerTest < ActionDispatch::IntegrationTest
setup do
#logo = plogos(:main_logo)
end
#...
test "should get edit" do
get edit_logo_url(#logo)
assert_response :success
end
#...
end

Persisted model via save method does not show up in sqlite3 database. Why?

i am new to RoR and probably miss something out.
Can you give me an idea what is wrong?
TestMethod in Unit Test
test "create" do
prices = [12,14,16]
prices.each {|p|
course = Course.new(:name => "j2ee", :price => p)
course.save!
puts course.persisted?
}
#Course.where({:price => 12...17}).all.each do |c|
Course.find_by_price(12) do |c|
puts c.price
end
end
Commandline Output running the test
Running tests:
true
true
true
12
..
like expected.
But why does't the db table contain rows?
sqlite3 test.sqlite3
sqlite> select count(*) from courses;
0
This is def. the right database. If i work with fixture data it is inserted correctly and is until the next testrun available.
Thankx a lot!
cheers
rob
Your question does not specify what testing framework you are using, but generally speaking, testing frameworks cleanup after themselves, which is the polite thing to do.
You did say that it works with fixtures, so you have nothing to worry about. But if you want to manually verify that persistence is working, open the console and type in your test.
prompt$ rails c
> Course.new(:name => "j2ee", :price => 12).save!
> Course.all
The console prints all courses. Note, if you are using bundler (which you should be), you may need to start the console with "bundle exec rails c".

How do I stub ::Rails.root in rspec?

I'm writing a gem that can be used both with and without rails. In a few places I use code like
path = Rails.root if defined?(::Rails)
and I want to test this logic with rspec. I have tried stubbing it like
stub(:"::Rails").should_receive(:root).and_return("/rails")
but this does not make defined?(::Rails) evaluate to true.
Even if defined?(::Rails) is evaluated to true, you still need a Rails object to inject the method stub. There might be several ways to do this, following is a example of my preferred approach:
before(:each) do
unless defined?(::Rails)
#mocked_rails_class = true
class ::Rails
end
end
end
it do
::Rails.should_receive(:root).and_return('/rails')
your_method.should == '/rails'
end
after(:each) do
# Clean up the Rails class if it's generated by the test case.
Object.send(:remove_const, :Rails) if #mocked_rails_class
end
I'm not sure if it works on all ruby version, but at least it can work on Ruby 1.9.x.

Failing to test Devise with Capybara

I'm building a Rails 3 app using Devise, with Capybara for UI testing. The following test is failing:
class AuthenticationTest < ActionController::IntegrationTest
def setup
#user = User.create!(:email => 'test#example.com',
:password => 'testtest',
:password_confirmation => 'testtest')
#user.save!
Capybara.reset_sessions!
end
test "sign_in" do
# this proves the user exists in the database ...
assert_equal 1, User.count
assert_equal 'test#example.com', User.first.email
# ... but we still can't log in ...
visit '/users/sign_in'
assert page.has_content?('Sign in')
fill_in :user_email, :with => 'test#example.com'
fill_in :user_password, :with => 'testtest'
click_button('user_submit')
# ... because this test fails
assert page.has_content?('Signed in successfully.')
end
end
... but I have no idea why. As you can see from the code, the user is being created in the database; I'm using the same approach to create the user as I did in seeds.rb.
If I run the test through the debugger, I can see the user in the database and verify that the page is loading. But still the authentication fails; I can verify this because if I change the assertion to test for the failure case, the test passes:
# verify that the authentication actually failed
assert page.has_content?('Invalid email or password.')
I'm used to Rails 2, & using Selenium for this sort of testing, so I suspect I'm doing something daft. Could someone please point me in the right direction here?
I was having the same issue and found a thread with a solution:
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
For the DatabaseCleaner stuff to work you'll need to include the database_cleaner gem. If you haven't used it before, you may need to rake db:test:prepare before rerunning your tests. I hope this works for you, too!
I've run into a similar problem before. Setting the password directly has some weird effects because it's supposed to be encrypted and stored with a salt--sometimes it works for me and other times it doesn't. I have a hard time remembering which specific cases were problematic. I'd recommend the following, in this order (for simplicity)
Verify that the password field is getting filled in properly and passed as the right param (not necessary if you're using Devise's autogenerated view and haven't touched it)
if your site can run in development mode (i.e. no log in bugs), then just boot it up and log in manually
If not, insert debugger as the first line in your sessions_controller. Then check params and make sure the password is correct and in params[:user][:password].
If you didn't override Devise's sessions_controller, then you can find your Devise path with bundle show devise. Then look for the create action within (devise path)/app/controllers/devise/sessions_controller.rb
Change your test setup to create a user through the web interface, to ensure the password gets set properly, then try running your test again
I had the same issue with a setup fairly similar to yours. In my case, switching to ActiveRecord sessions in the initializer solved the problem.
Additionally, make sure you call #user.skip_confirmation! if you are using the "confirmable" module in devise.

How to test routes with Rspec 2 in Rails 3?

I can't find anything explaining how to test routes in Rails 3. Even in the Rspec book, it doesn't explain well.
Thanks
There is a brief example on the rspec-rails Github site. You can also use the scaffold generator to produce some canned examples. For instance,
rails g scaffold Article
should produce something like this:
require "spec_helper"
describe ArticlesController do
describe "routing" do
it "routes to #index" do
get("/articles").should route_to("articles#index")
end
it "routes to #new" do
get("/articles/new").should route_to("articles#new")
end
it "routes to #show" do
get("/articles/1").should route_to("articles#show", :id => "1")
end
it "routes to #edit" do
get("/articles/1/edit").should route_to("articles#edit", :id => "1")
end
it "routes to #create" do
post("/articles").should route_to("articles#create")
end
it "routes to #update" do
put("/articles/1").should route_to("articles#update", :id => "1")
end
it "routes to #destroy" do
delete("/articles/1").should route_to("articles#destroy", :id => "1")
end
end
end
Zetetic's answer explains how to test routes. This answer explains why you shouldn't do that.
In general, your tests should test the behavior exposed to the user (or client object), not the implementation by which that behavior is provided. Routes are user-facing: when the user types in http://www.mysite.com/profile, he doesn't care that it goes to ProfilesController; rather, he cares that he sees his profile.
So don't test that you're going to ProfilesController. Rather, set up a Cucumber scenario to test that when the user goes to /profile, he sees his name and profile info. That's all you need.
Again: don't test your routes. Test your behavior.