I have run the tests and it doesn't seem that the user get created by a Factory Girl. Here's what I got:
reports_controller_spec.rb
require 'rails_helper'
RSpec.describe ReportsController do
let(:user) { create :user }
before { sign_in user }
describe 'GET #subjects' do
subject { get :subjects }
it_behaves_like 'template rendering action', :subjects
end
end
factories/users.rb
FactoryGirl.define do
factory :user do
email { Faker::Internet.safe_email }
password { Faker::Internet.password }
end
end
And when I run the test I get this error:
ReportsController
GET #subjects
behaves like template rendering action
example at ./spec/support/shared/template_rendering_action.rb:2 (FAILED - 1)
Failures:
1) ReportsController GET #subjects behaves like template rendering action
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `password=' for #<User:0x000000063abd20>
Shared Example Group: "template rendering action" called from ./spec/controllers/reports_controller_spec.rb:11
...
I do not understand why it doesn't work. Anyone could point me to the mistake? Thanks.
Edit: I'm using devise.
If you're using Devise, you need to add the password_confirmation to your :user factory
Related
I am just started learning Ruby on Rails. Current chapter is about testing, while I do testing it is happening like this? What do i need to do? and What should I learn more to understand testing ruby on rails ?
Here's my Controller test code.
require 'test_helper'
class CategoriesControllerTest < ActionDispatch::IntegrationTest
def setup
#category = Category.create(name: "sports")
#user = User.create(username: "supyaeaung", email: "supyaeaung27714#gmail.com", password: "hlaing", admin: true)
end
test "should get new" do
sign_in_as(#user, "password")
get new_category_path
assert_response :success
end
Here's the error. What should I do ?
Error:
CategoriesControllerTest#test_should_get_new:
NoMethodError: undefined method `confirm' for #<User:0x00007fd0781e0370>
test/controllers/categories_controller_test.rb:15:in `block in <class:CategoriesControllerTest>'
Your controller, on line 15 tries to call method confirm on User object:
NoMethodError: undefined method `confirm' for #<User:0x00007fd0781e0370>
test/controllers/categories_controller_test.rb:15
You probably didn't implement it.
I'm basically getting an error when I'm trying to use a factory I created for a Post model in Ruby on Rails.
Here's the full error:
Failure/Error: post = create(:post)
NoMethodError:
undefined method `create=' for #<Post:0x007fbf1be6e510>
Did you mean? created_at=
# ./spec/models/post_spec.rb:6:in `block (2 levels) in <top (required)>'
Here's the file for the factories:
spec/factories/post.rb
FactoryGirl.define do
factory :post do
title "Hello"
content "Hello, my name is Jacob."
user create(:user)
user_id 1
end
end
spec/models/post_spec.rb
require 'rails_helper'
require 'spec_helper'
describe Post do
it "has a valid factory" do
post = create(:post)
expect(post).to(be_valid)
end
end
I do have a spec/support/factory_girl.rb file which includes the FactoryGirl::Syntax::Methods. This file is loaded by spec/rails_helper.rb.
Also, the create(:user) line works and I'm able to use the user factory in the rails console, but not the post factory.
Any help would be fantastic. Thank you!
In your post factory, you have the syntax wrong for defining an associated record. Try defining it like this:
FactoryGirl.define do
factory :post do
title "Hello"
content "Hello, my name is Jacob."
user
end
end
You just need to state that the post has a user, and you certainly shouldn't be setting them all to have a specific user_id ... since each post will create a new user unless told otherwise and you have no idea what user_id will be generated.
I run test, display error.
Failures:
1) ContractsController POST #create with valid attributes redirects to payment page
Failure/Error: #proposal = Proposal.find(params[:proposal_id])
ActiveRecord::RecordNotFound:
Couldn't find Proposal with 'id'=
require 'rails_helper'
describe ContractsController do
login_client
describe 'POST #create' do
let(:proposal) { create(:proposal) }
let(:contract) { create(:contract) }
context 'with valid attributes' do
it 'redirects to payment page' do
post :create, contract: attributes_for(:contract)
expect(response).to redirect_to payment_new_path
end
end
end
end
factory girls:
FactoryGirl.define do
factory :contract do
sequence(:title) { |n| "translation#{n}" }
amount 150
additional_information 'X' * 500
due_date { 21.days.from_now }
proposal
client
contractor
end
end
FactoryGirl.define do
factory :proposal do
description text
amount 150
project
user
end
end
I'm sure you're getting this error because of the use of FactoryGirl#attributes_for. Why? When you use the attributes_for method, it returns a non-persisted hash attribute for the resource. The thing about attributes_for however is that it doesn't honor association, which makes sense(in order to keep FactoryGirl ORM agnostic). A suggested way around this is to use or define a custom strategy:
build(:contract).attributes
Find more useful references here
This is my Spec file:
require 'rails_helper'
RSpec.describe Programmes::ReportsController, :type => :controller do
let!(:programme) { create(:programme) }
context 'authenticated user' do
describe 'GET index' do
it 'responds with a 200 OK status code' do
get :index, params: { id: programme.id }
expect(response).to have_http_status(:success)
end
end
end
end
This is my Factory;
FactoryGirl.define do
factory :programme do
name { Faker::Lorem.word }
description { Faker::Lorem.sentence(3) }
end
end
This is my Controller;
class Programmes::ReportsController < ApplicationController
def index
end
def create
end
end
I can't seem to get this spec to pass. The route works fine in the browser; eg
http://localhost:3000/programmes/{:id}/reports
The error I have is:
Failures:
1) Programmes::ReportsController authenticated user GET index responds with a 200 OK status code
Failure/Error: let!(:programme) { create(:programme) }
NoMethodError:
undefined method `create' for #<RSpec::ExampleGroups::ProgrammesReportsController::AuthenticatedUser::GETIndex:0x007fac78b1b440>
# /Users/mike/.rvm/gems/ruby-2.2.3/gems/actionpack-5.0.0/lib/action_dispatch/testing/assertions/routing.rb:172:in `method_missing'
I am quite new to Ruby (and Rails). I don't think the Programme object is being created in FactoryGirl - but I don't really know how to find out if that's the case
Did you require 'factory_girl' in spec_helper?
i create a customized devise registration controller and i want to test it with rspec.
I've tried it with a very simple test :
it "creates a new parent" do
Parent.should receive(:new)
post :create
end
but i get this exception:
Failures:
1) Parent::RegistrationsController POST create creates a new parent
Failure/Error: post :create, { :commit => "Daftar",
uncaught throw `warden'
# /home/starqle/.rvm/gems/ree-1.8.7-2010.02/gems/devise-1.1.3/lib/devise/hooks/timeoutable.rb:16:in `throw'
# /home/starqle/.rvm/gems/ree-1.8.7-2010.02/gems/devise-1.1.3/lib/devise/hooks/timeoutable.rb:16
I already put this line within my test:
describe Parent::RegistrationsController do
include Devise::TestHelpers
end
I also already put this line:
request.env["devise_mapping"] = Devise.mappings[:parent]
anybody have ideas to solve this problem?
My previous answer is a little confusing. sorry.
Updated answer: root cause is user is not "confirmed" before "sign in".
#user.confirm!
sign_in #user
then everything is fine.
I am fresher in ruby.
I am using rails 3 with devise and factory girl.
I was searching for how to authenticate user for rspec.
I was stucked at before_filter: authenticate_user! in controller.
Finally I got solution (thanks to Siwei Shen)
What I am doing is
include TestHelpers in spec/spec_helper.rb
2.
require 'spec_helper'
describe StudentsController do
before(:each) do
#user = Factory.create(:user) #:user from factory girl with admin privilages
#request.env['devise.mapping'] = :user
#user.confirm!
sign_in #user
end
it "can get index of student" do
get :index
response.should be_suclogin_as #user
end
it "can create student" do
#in student model : validates :name, :presence=> true
post :create, :student => {name => "student1" }
answer = Student.find_by_name("student1")
answer.name.should == "student1"
end
end