Reputation: 7220
I have been starting to learn testing in my Rails app and am using rSpec and Shoulda.
I have the following test which works:
it { should respond_to(:park_name) }
However, what I don't understand is, what is this being run on? Is this being run on the Model itself or an instance of the model and if it's an instance of the Model then is it automatically using my Factory Girl factory?
Any simple explanations on what is actually occurring here?
UPDATE:
Ok, So I have this:
describe 'validations' do
subject { FactoryGirl.build(:coaster) }
it { should validate_presence_of(:name) }
it { should validate_presence_of(:speed) }
it { should validate_presence_of(:height) }
end
But the tests are failing. Any ideas?
Coaster.rb:
class Coaster < ActiveRecord::Base
extend FriendlyId
friendly_id :slug, use: :slugged
belongs_to :park
belongs_to :manufacturer
attr_accessible :name,
:height,
:speed,
:length,
:inversions,
:material,
:lat,
:lng,
:park_id,
:notes,
:manufacturer_id,
:style,
:covering,
:ride_style,
:model,
:layout,
:dates_ridden,
:times_ridden,
:order,
:on_ride_photo
scope :by_name_asc, lambda {
order("name ASC")
}
scope :made_from, lambda { |material|
where("material = ?", material)
}
scope :wooden, lambda {
made_from "wood"
}
scope :steel, lambda {
made_from "steel"
}
delegate :name, :location_1, :location_2, :location_3, :location_4,
to: :park,
allow_nil: true,
prefix: true
delegate :name, :url,
to: :manufacturer,
prefix: true
validates :name,
:presence => true
validates :height,
allow_nil: true,
numericality: {greater_than: 0}
validates :speed,
allow_nil: true,
numericality: {greater_than: 0}
validates :length,
allow_nil: true,
numericality: {greater_than: 0}
Test Results:
1) Coaster validations should require speed to be set Failure/Error: it { should validate_presence_of(:speed) } Expected errors to include "can't be blank" when speed is set to nil, got no errors # ./spec/models/coaster_spec.rb:75:in `block (3 levels) in '
2) Coaster validations should require height to be set Failure/Error: it { should validate_presence_of(:height) } Expected errors to include "can't be blank" when height is set to nil, got no errors # ./spec/models/coaster_spec.rb:76:in `block (3 levels) in '
SIMILAR QUESTION:
I have this test:
describe 'methods' do
subject { FactoryGirl.build(:coaster) }
it "should return a formatted string of coaster name at park name" do
name_and_park.should eq('Nemesis at Alton Towers')
end
end
Coaster.rb:
def name_and_park
[name, park.name].join (' at ')
end
Error when running the test:
2) Coaster methods should return a formatted string of coaster name at park name Failure/Error: name_and_park.should eq('Nemesis at Alton Towers') NameError: undefined local variable or method
name_and_park' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_6:0x007f84f4161798> # ./spec/models/coaster_spec.rb:111:in
block (3 levels) in '
It says name_and_park cannot be called but surely that method should be being called on the instance of Coaster that is being made in the subject line? No?
Upvotes: 4
Views: 2665
Reputation: 29439
It's being run on "subject", which is either explicitly defined through the subject
method or implicitly defined by passing in a class as the argument to describe
, in which case an instance of that class is instantiated and made the subject of the test. See https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/subject/explicit-subject and https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/subject/implicit-subject
As for the answer to the Update question, in your model validations for :speed
and :length
, you have allow_nil: true
, which is why those two tests are failing. Part of the definition of validates_presence_of
is that nil
is not a settable value.
As for your latest question, I think you may be confused about the use of implicit subjects. If should
is used by itself, it will indeed default to whatever the subject
is, but if you include a subject yourself, as you have in this case with name_and_park
, it won't treat that as a method of the default subject, it must have a definition within the current namespace. In your case, you would need to say subject.name_and_park.should ...
.
On a related aside, StackOverflow is best used when you ask a specific question or related set of questions and get an answer. For a variety of reasons, it's not intended for ongoing debugging sessions. One of those reasons is that it becomes tedious tracking substantial, sequential updates of the original question and answer.
Upvotes: 3