Reputation: 3573
I'm trying to make some simple model test:
/app/models/album.rb:
class Album < ActiveRecord::Base
has_many :slides, dependent: :restrict_with_exception
validates :name, presence: true
end
/spec/model/album_spec.rb:
require 'spec_helper'
describe Album do
before do
@album = Album.new(name: 'Example Album')
end
describe "when album name is already taken" do
before do
another_album = @album.dup
another_album.save
end
it { should_not be_valid }
end
end
I was expecting it to fail first (as I have no validates :uniqueness
and index on the name field) but it passed. So I changed:
it { should_not be_valid }
to
it { should be_valid }
To see what's going on and this is what I got:
1) Album when album name is already taken should be valid
Failure/Error: it { should be_valid }
expected #<Album id: nil, name: nil, created_at: nil, updated_at: nil> to be valid, but got errors: Name can't be blank
# ./spec/models/album_spec.rb:14:in `block (3 levels) in <top (required)>'
I would like to ask you what I did wrong.
One more thing is if I can/should use expect
rather than should
syntax here ? I read somewhere that should
is a bit deprecated and not expect
is recomended but I don't know how to use it for model testing (I have it on my Controller/View test in form of expect(page)
or expect(current_path)
. What argument can I use for model ?
Upvotes: 0
Views: 290
Reputation: 1963
I have never seen the it
syntax that you are using. First thing, I would checkout the quick start documentation available here: https://github.com/rspec/rspec-rails#model-specs and then make sure that you are familiar with this set of docs as well: http://rspec.info/
From the example on github:
require "spec_helper"
describe User do
it "orders by last name" do
lindeman = User.create!(first_name: "Andy", last_name: "Lindeman")
chelimsky = User.create!(first_name: "David", last_name: "Chelimsky")
expect(User.ordered_by_last_name).to eq([chelimsky, lindeman])
end
end
You would want to change your second describe
to an it
and then use one or more expect
to determine if the test passes. it
takes a string that appears in the test output. So generally you want to make it something expressive. Additionally there is no need to use before blocks here. You can do everything in the it
block:
require 'spec_helper'
describe Album do
it "fails validation when album name is already taken" do
album = Album.new(name: 'Example Album')
another_album = album.dup
expect {another_album.save!}.to raise_error(ActiveRecord::RecordInvalid,'Validation failed: This question is no longer active.')
end
end
Upvotes: 2
Reputation: 53018
Setup an explicit subject
before your example:
subject {@album}
it { should_not be_valid }
Currently, as per the failure error#<Album id: nil, name: nil, created_at: nil, updated_at: nil>
an implicit blank instance of Album
is created as no explicit subject
is found before the example.
Upvotes: 1