rails 4 RSpec test validations - ruby-on-rails

It looks like you used to be able to write RSpec tests with the following syntax
it { should validate_presence_of :privacy }
However I'm receiving the following error
error undefined method `validate_presence_of' for #<RSpec::ExampleGroups::Review:0x007fd819c1bdc8>
I can write tests the following way but the above syntax is much simpler
it "should require privacy" do
expect(FactoryGirl.build(:review, privacy: "")).to_not be_valid
end
Is there a 1 liner to test validations using Rails 4.2 and rspec-rails 3.0? I feel like I'm missing something...

Yes there is:
it { is_expected.not_to be_valid }
You can read all about it at Relish
Edited to add clarification:
This assumes the subject is either explicitly stated, like
subject{ FactoryGirl.build(:wiget) }
or is able to be inferred.

Related

Where to place helper specs (specs that test additional things in a Rails app)

Not to be confused by the title, I am not asking where I can place specs that test Rails helpers, but helpers specs that test additional things in a Rails app. For example, a spec that checks whether all translations are in place. Or that FactoryGirl factories are valid.
I know the guys at FactoryGirl recommend putting this check on RSpec's before :suite, but I prefer to leave it aside in a spec file of its own (so that it doesn't get executed when I want to run a single spec, for example).
So, what's the place to put these kind of specs?
I put FactoryGirl's specs in spec/models/*_spec.rb. For example
# spec/models/user_spec.rb
describe User do
describe "factories" do
it { expect(build(:user)).to be_valid }
end
end
For other kinds of specs, say for service objects, I put them in spec/services/*_spec.rb. RSpec will automatically detect them.
Edited
For translations, I test them in view specs. Firstly, set config to raise error on translations are missing.
# config/environments/test.rb
# Raises error for missing translations
config.action_view.raise_on_missing_translations = true
Then in the view spec,
describe "pages/welcome" do
it { expect { render }.not_to raise_error }
end

New Rspec 3 way to stub model (Rails 4.2/Rspec 3.1)

On one Rspec test (which works fine), I have a deprecation warning
Using stub from rspec-mocks' old :should syntax without explicitly enabling the syntax is deprecated. Use the new :expect syntax or explicitly enable :should instead.
How should I change this test to be compliant with Rspec 3?
I am testing that the field company name exists/is not empty, then I have to validate presence of the company phone number field. I used to use 'stub' but it does not work properly and I'd like to move to the new Rspec 3 way.
/spec/models/company_spec.rb
describe "test on company name" do
context "test" do
before { subject.stub(:company_name?) { true } }
it { is_expected.to validate_presence_of(:company_phone_number) }
end
end
To stub a method under RSpec 3 use allow/receive:
allow(subject).to receive(:company_name?).and_return(true)
If you would to set an expectation that will fail if company_name? is never called:
expect(subject).to receive(:company_name?).and_return(true)
It could be like this:
describe "test on company name" do
context "test" do
before { allow(subject).to receive(:company_name?).and_return(true) }
...
end
end

Rails RSpec: Controller Testing, checking if errors Array of model is filled with entries if new record cannot be created due to validation error

I have a still pretty simple Rails application that I want to develop using BDD with Cucumber and TDD with RSpec. Currently, I am hanging at a test where I want to check that if a new instance of an Organizer (that's the model I have) cannot be created due to a validation error. I would like to check that the errors Array of the object to be created is not empty so that I can be sure that error messages are available for showing them in the view.
require 'spec_helper'
describe OrganizersController do
render_views
describe "POST 'create'" do
describe "with invalid arguments" do
before(:each) do
request.env["HTTP_REFERER"] = organizers_new_path
#organizer_args = { :name => "" }
end
it "should return a non-empty list of errors" do
post 'create', :organizer => #organizer_args
#organizer.errors.empty?.should_not be_true
end
end
end
end
I am developing based on Rails 3.2.9 with RSpec 2 and cucumber-rails.
Any suggestions are appreciated. Thanks!
You should use assigns method to get instance variable from controller action:
assigns(:organizer).errors.empty?.should_not be_true
The latest preferred syntax is:
expect(assigns(:organizer).errors.empty?).to_not be_true
thanks for the answer guys but I'd like to suggest a slightly nicer syntax:
expect(assigns(:organizer).errors).to_not be_empty
(unrelated to the question 👇)
Basically whenever you have a method that ends with ? you'll have the corresponding rspec matcher that starts with be_ e.g.
1.odd? #=> true
expect(1).to be_odd

Remarkable active record association

i'm using gem Remarkable activerecord for association. i've installed remarkable and remarkable activerecrod both gem. i've added both gem in my Gemfile. i've added "remarkable_activerecord" as required in spec_helper.rb.
describe Authentication do
FactoryGirl.build(:authentication).should belong_to(:user)
end
i got error:
Authentication
Failure/Error: it { should belong_to(:user) }
NoMethodError:
undefined method `belong_to' for #
what should be done now..?? thanks in advance
You need to define what it refers to by including subject { something } right above the test example.
You are missing some RSpec syntax. In order to use the "should" assertion, it has to be within an "it" or "specify" block. There are a number of different ways you can do this, but here's one concise way:
describe Authentication do
subject { FactoryGirl.build(:authentication) }
it { should belong_to(:user) }
end

How to use Capybara Rspec Matchers to test a presenter?

I'm trying to test a presenter method using a Capybara RSpec matcher.
Lets say I have a method that renders a button. This would be the test I would write if I wasn't using capybara rspec matchers:
it "should generate a button" do
template.should_receive(:button_to).with("Vote").
and_return("THE_HTML")
subject.render_controls.should be == "THE_HTML"
end
Using capybara rspec matchers, I want to do this:
it "should render a vote button" do
subject.render_controls.should have_button('Vote')
end
This approach was proposed in this article http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/. In the article, the author explains it like this: "I decided to change up my spec setup a bit in order to pass in a template object which included the actual Rails tag helpers. Then I included the Capybara spec matchers for making assertions about HTML."
However, I don't understand this. How can you use capybara rspec matchers when render_controls only returns a content_tag?
Even though luacassus's answer is correct, I found what the problem was. I wasn't including capybara rspec matchers in the test. If you don't include Capybara rspec matchers, you will an error like this: undefined method has_selector? for ActiveSupport::SafeBuffer:0x9449590.
When you include the rspec matchers, there is no need to use Capybara String method, since rspec matchers match against a string already.
I leave here a more detailed example.
require_relative '../../app/presenters/some_presenter'
require 'capybara/rspec'
describe 'SomePresenter'
include Capybara::RSpecMatchers
let(:template) { ActionView::Base.new }
subject { Presenter.new(template) }
it "should render a vote button" do
subject.render_controls.should have_button('Vote')
end
end
Check out Capybara.string method: http://rubydoc.info/github/jnicklas/capybara/master/Capybara#string-class_method
With this method you should be able to write something like that:
subject { Capybara.string(presenter.render_controls }
it { should have_button('Vote') }

Resources