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
Related
they fail with: unitialized constant ActiveModel::SecurePassword::InstanceMethodsOnActivation
I'm trying to update a rails 5.2 app to the rails 6 beta, and everything seems to be working fine except for my validate_presence_of specs.
For example
RSpec.describe Post, type: :model do
context 'validations' do
subject { Post.new(body: Faker::Movie.quote)}
it { should validate_presence_of :body }
it { should validate_length_of(:body).is_at_most(5000).on(:create) }
end
end
the validate_length_of passes fine, and the validate_presence of does not. Posts do belong to a user that inherits from a Clearance::User, but I'm not sure why the constant would vary on different tests for the same model?
I've made this work.
There's a Pull Request to shoulda_matchers here:
https://github.com/thoughtbot/shoulda-matchers/pull/1169
Until the shoulda_matchers team merge it, use my version here:
https://github.com/morsedigital/shoulda-matchers
In your Gemfile:
gem 'shoulda-matchers', groups: [:test], git: 'https://github.com/morsedigital/shoulda-matchers'
Turns out this is a bug with shoulda-matchers.
https://github.com/thoughtbot/shoulda-matchers/issues/1167
In my case this was quick fix:
# spec/rails_helper.rb - add to bottom
class ActiveModel::SecurePassword::InstanceMethodsOnActivation; end;
I'm practicing testing (just got into it), and am wondering whether it's better to use shoulda-matchers or Factory Girl - or a combination of both - in testing models. For example, I currently just use the simple shoulda-matchers test, which is nice and straightforward:
RSpec.describe User, :type => :model do
describe User do
it { should validate_presence_of(:username) }
it { should validate_presence_of(:password_decoded) }
it { should validate_length_of(:password).is_at_least(3) }
it { should validate_presence_of(:session_token) }
it { should have_one(:shopping_cart)}
end
end
But, from my understanding, this doesn't actually instantiate a User object like Factory Girl would. Is the above "sufficient" for testing? Any thoughts appreciated!
factory_girl and shoulda-matchers do two different things. Most Rails applications need both of those things. It's not either-or. The fact that the same people (Thoughtbot) are behind both gems is a good clue that they're both useful at the same time.
factory_girl allows you to create (only in memory or in the database) objects to use in your tests. Most applications need to create similar objects over and over again in their tests; factory_girl removes the duplication in doing that. It also allows you to customize a predefined object easily (more easily than a Rails fixture, for example). The model spec you showed doesn't need factory_girl, but if you have any code in your models more complicated than basic configuration it will probably be helpful to use factory_girl to create models to test.
shoulda-matchers makes it easier to assert that you got the results you expected in your tests. It provides RSpec matchers for asserting things about models and controllers. Most applications will find shoulda-matchers' ActiveModel matchers useful in ensuring that their models are well validated. (Personally I get more use out of shoulda-matchers' ActiveModel matchers than the ActiveRecord matchers.)
For basic associations and validations, I think shoulda matchers are fine. I use Factories to test other methods and more complex validations. Here's a simple example for a method that returns a value based on an instance's attributes. I've also shown how to use sequence to always generate a unique email address which can often trip you up in tests.
class User
def fullname
"#{firstname} #{surname}"
end
end
factories/users.rb
FactoryGirl.define do
sequence(:username) { |n| "user-#{n}" }
factory :user do
email { |_u| "#{FactoryGirl.generate(:username)}#example.com" }
password 'password'
password_confirmation 'password'
firstname 'John'
surname 'Smith'
end
end
user_spec.rb
RSpec.describe User do
describe "#fullname" do
it "returns the first and surnames separated by a space" do
user = FactoryGirl.create(:user)
expect(user.fullname).to eq "John Smith"
end
end
end
If you are going to have small models and tests you may create your example data using seeds but if you are going to add feature tests as well then I would suggest to use FactoryGirl.
I believe shoulda-matchers is a must for all tests.
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.
I'm writing integration tests using Rspec and Capybara. I've noticed that quite often I have to execute the same bits of code when it comes to testing the creation of activerecord options.
For instance:
it "should create a new instance" do
# I create an instance here
end
it "should do something based on a new instance" do
# I create an instance here
# I click into the record and add a sub record, or something else
end
The problem seems to be that ActiveRecord objects aren't persisted across tests, however Capybara by default maintains the same session in a spec (weirdness).
I could mock these records, but since this is an integration test and some of these records are pretty complicated (they have image attachments and whatnot) it's much simpler to use Capybara and fill out the user-facing forms.
I've tried defining a function that creates a new record, but that doesn't feel right for some reason. What's the best practice for this?
There are a couple different ways to go here. First of all, in both cases, you can group your example blocks under either a describe or context block, like this:
describe "your instance" do
it "..." do
# do stuff here
end
it "..." do
# do other stuff here
end
end
Then, within the describe or context block, you can set up state that can be used in all the examples, like this:
describe "your instance" do
# run before each example block under the describe block
before(:each) do
# I create an instance here
end
it "creates a new instance" do
# do stuff here
end
it "do something based on a new instance" do
# do other stuff here
end
end
As an alternative to the before(:each) block, you can also use let helper, which I find a little more readable. You can see more about it here.
The very best practice for your requirements is to use Factory Girl for creating records from a blueprint which define common attributes and database_cleaner to clean database across different tests/specs.
And never keep state (such as created records) across different specs, it will lead to dependent specs. You could spot this kind of dependencies using the --order rand option of rspec. If your specs fails randomly you have this kind of issue.
Given the title (...reusing code in Rspec) I suggest the reading of RSpec custom matchers in the "Ruby on Rails Tutorial".
Michael Hartl suggests two solutions to duplication in specs:
Define helper methods for common operations (e.g. log in a user)
Define custom matchers
Use these stuff help decoupling the tests from the implementation.
In addition to these I suggest (as Fabio said) to use FactoryGirl.
You could check my sample rails project. You could find there: https://github.com/lucassus/locomotive
how to use factory_girl
some examples of custom matchers and macros (in spec/support)
how to use shared_examples
and finally how to use very nice shoulda-macros
I would use a combination of factory_girl and Rspec's let method:
describe User do
let(:user) { create :user } # 'create' is a factory_girl method, that will save a new user in the test database
it "should be able to run" do
user.run.should be_true
end
it "should not be able to walk" do
user.walk.should be_false
end
end
# spec/factories/users.rb
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
username { Faker::Internet.user_name }
end
end
This allows you to do great stuff like this:
describe User do
let(:user) { create :user, attributes }
let(:attributes) { Hash.new }
it "should be able to run" do
user.run.should be_true
end
it "should not be able to walk" do
user.walk.should be_false
end
context "when user is admin" do
let(:attributes) { { admin: true } }
it "should be able to walk" do
user.walk.should be_true
end
end
end
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') }