Rails - User.count didn't change by 1 - ruby-on-rails

My personal website is being built on rails but I'm stuck with the User.count for the login area not updating. Been sitting with this for a day trying to get it to work but no luck so far. I've included all the code if someone could spot my error as I can't see it.
class UsersControllerTest < ActionController::TestCase
setup do
#user = users(:one)
#input_attributes = {
name: 'luchia',
password: 'secret',
password_confirmation: 'secret'
}
end
test "should create user" do
assert_difference('User.count') do
post :create, user: #input_attributes
end
assert_redirected_to users_path
end
Then there is my User Controller
# GET /users/1
# GET /users/1.json
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to users_url, notice: "User #{#user.name} was successfully created." }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
And my Terminal error:
$ rake test
Run options: --seed 11633
# Running tests:
....[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
....................F......
Finished tests in 1.143021s, 27.1211 tests/s, 45.4935 assertions/s.
1) Failure:
UsersControllerTest#test_should_create_user [/Users/lucybloomfield/Documents/luchia /test/controllers/users_controller_test.rb:25]:
"User.count" didn't change by 1.
Expected: 3
Actual: 2
31 tests, 52 assertions, 1 failures, 0 errors, 0 skips
Would appreciate anyone's help.
////////////////
Mmkay, this is what I ended up coming up with but it's not very concise. Rake test is completing with this so I guess it will have to do.
test "should create user" do
assert_difference('User.count') do
post :create, {:user => {'name' => 'luchia', 'password' => 'secret', 'password_confirmation' => 'secret'}}
.to change(User, :count).by(1)
end
assert_redirected_to users_path
end
//////////////
Edit again, the above bit of code fails on the second rake test.

Example with capybara and cucumber
describe "new" do
before do
visit new_user_path
end
it { should have_title(I18n.t("user.new")) }
describe "with invalid information" do
before { find("form#new_user").submit_form! }
it { should have_title(I18n.t("user.new")) }
it { should have_selector("div#alerts") }
end
describe "with valid information" do
before do
fill_in "user_name", :with => "user_name"
fill_in "user_email", :with => "user#example.com"
fill_in "user_password", :with => "123456"
fill_in "user_password_confirmation", :with => "123456"
find("form#new_user").submit_form!
end
it { should have_content(I18n.t("user.success"))}
end
end

You have to do a
puts YAML::dump(#user.save!)
in your method create of UsersControlller
def create
#user = User.new(user_params)
puts YAML::dump(#user.save!)
...
end
To see why it doesn't save.
Then check your user_params permit if it necessary

set
I18n.enforce_available_locales = false
to your config/application.rb
inside as exampled:
module MyApp
class Application < Rails::Application
...
I18n.enforce_available_locales = false
end
end
and restart server

Related

An object instance not getting created in my test

The following is my test and everything works. The form gets filled with a name and image in the ui when I run the test. If I also test the presence of the user's name being created in the ui when I visit groups_path the test also passes. The only issue is that a group is not getting created. I'm not sure what I'm missing.
I'm using devise for authentication
create_group_spec.rb
require 'rails_helper'
RSpec.describe 'Creating a group', type: :feature do
before :each do
user = User.create!(name: 'Test user', email: 'test#gmail.com', password: '123456',
password_confirmation: '123456')
login_as(user, scope: :user)
end
scenario 'adds a new group when name and image is entered' do
visit new_group_path
fill_in('Name', with: 'Sports')
attach_file('Icon', "#{Rails.root}/integration_test_image/test.jpg")
sleep(3)
click_on 'Create Group'
visit groups_path
expect(page).to have_content('Sports')
end
end
groups_controller.rb
def create
#group = Group.new(group_params)
#group.user = current_user
respond_to do |format|
if #group.save
format.html { redirect_to groups_url, notice: 'Group was successfully created.' }
format.json { render :show, status: :created, location: #group }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #group.errors, status: :unprocessable_entity }
end
end
end
private
def group_params
params.require(:group).permit(:name, :icon)
end
No more sleeping on the job. sleep x doesn't actually guarentee that whatever your waiting for is actually finished - it just makes your tests slower and potentially flappy.
require 'rails_helper'
RSpec.describe 'Creating a group', type: :feature do
before :each do
# You should be using fixtures or factories instead.
user = User.create!(name: 'Test user', email: 'test#gmail.com', password: '123456',
password_confirmation: '123456')
login_as(user, scope: :user)
end
scenario 'adds a new group when name and image is entered' do
visit new_group_path
fill_in('Name', with: 'Sports')
# use a block instead of sleep
# images should also go in /spec/support or /spec/fixtures
attach_file('Icon', Rails.root.join("/integration_test_image/test.jpg")) do
click_on 'Create Group' # no need to visit since it will redirect
expect(page).to have_content('Sports') # have_content waits for the page to load
end
end
end
I fixed it by adding sleep(1) after the click_on 'Create Group' line. I think by visiting the groups_path it happens too fast even before the group object creation is complete hence it becomes unavailable in the ui and is the reason for the test failing. Delaying the switch to the page by 1s ensures the object completes being created and is available when the page is rendered hence the test passing.

rspec for the controller without factory girl

I am trying to write spec code for my controller it gets failed. And i am not sure where it gets failed.
Controller Code
def index
#users = User.all
end
def update
authorize! :update, #user
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to user_index_path }
else
format.html { render :index }
end
end
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.permit(:active)
end
Spec Code for the above controller
RSpec.describe UserController, type: :controller do
describe 'GET #index' do
let(:user) {User.create!(name: "hari")}
context 'with user details'do
it 'loads correct user details' do
get :index
expect(response).to permit(:user)
end
end
context 'without user details' do
it 'doesnot loads correct user details' do
get :index
expect(response).not_to permit(:user)
end
end
end
describe 'Patch #update' do
context 'when valid params' do
let(:attr) do
{active: 'true'}
end
before(:each) do
#user = subject.current_user
put :update, params: { user: attr }
#user.reload
end
it 'redirects to user_index_path ' do
expect(response).redirect_to(user_index_path)
end
it 'sets active state' do
expect(#user.active?('true')).to be true
end
end
context 'when invalid param' do
let(:attr) do
{active: 'nil'}
end
before(:each) do
#user = subject.current_user
put :update, params: { user: attr }
#user.reload
end
it 'render index' do
expect(respone.status).to eq(200)
end
it 'doesnot change active state' do
expect(#user.active?(nil)).to be true
end
end
end
end
I am just a beginner and tried the spec code for my controller by checking https://relishapp.com/rspec/rspec-rails/docs/gettingstarted. Can you help me where my spec goes wrong or could anyone give me a few test examples for these methods or could redirect me to an rspec guide? the index method is getting failed
and my
terminal log is
1) UserController GET #index with user details loads correct user details
Failure/Error: expect(response).to permit(:user)
NoMethodError:
undefined method `permit' for #<RSpec::ExampleGroups::UserController::GETIndex::WithUserDetails:0x00005614152406b0>
Did you mean? print
# ./spec/controllers/user_controller_spec.rb:10:in `block (4 levels) in <top (required)>'

Param is missing in rspec test

I have the following RSpec test defined:
test 'invalid signup information' do
get signup_path
assert_no_difference 'User.count' do
post users_path, params: { user: { name: '',
email: 'user#invalid',
password: 'foo',
password_confirmation: 'bar' } }
end
assert_template 'users/new'
end
And the following Controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to new_user_path
else
render :new
end
end
def show
#user = User.find(params[:id])
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
If I execute rake test I get the following error:
ERROR["test_invalid_signup_information", UserSignupTest, 0.35556070700022246]
test_invalid_signup_information#UserSignupTest (0.36s)
ActionController::ParameterMissing: ActionController::ParameterMissing: param is missing or the value is empty: user
app/controllers/users_controller.rb:23:in `user_params'
app/controllers/users_controller.rb:8:in `create'
test/integration/user_signup_test.rb:7:in `block (2 levels) in <class:UserSignupTest>'
test/integration/user_signup_test.rb:6:in `block in <class:UserSignupTest>'
The test runs without problems if i delete the require statement in user_params. But I do send a user - So why does it fail?
I do not if this is right but in my opinion, you created an integration test but should be a test controller.
See this example
# spec/controllers/contacts_controller_spec.rb
# rest of spec omitted ...
describe "POST create" do
context "with valid attributes" do
it "creates a new contact" do
expect{
post :create, contact: {name: 'test'}
}.to change(Contact,:count).by(1)
end
more info for integration test

Signup Validation Test didn't change by 1

Signup Test Validation not working. Here is the code.
test "valid signup information" do
get signup_path
assert_difference 'User.count', 1 do
post_via_redirect users_path, user:{
name: "Example User",
email: "user#invalid.com",
password: "password",
password_confirmation: "password "
}
end
assert_template 'users/show'
end
Here is the result of Minitest.
"User.count" didn't change by 1.
Expected: 1
Actual: 0
I have done the invalid test, it works fine. the valid path is not working, when i add 1 to the block.
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
flash[:success] = "Welcome to the app"
redirect_to user_url(#user)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
Updated

testing "create" method in ruby with rspec

I have written this controller code in Ruby on Rails
class PostsController < ApplicationController
before_filter :authenticate_user!
def index
#posts = Post.all(:order => "created_at DESC")
respond_to do |format|
format.html
end
end
def create
#post = Post.create(:message => params[:message])
respond_to do |format|
if #post.save
format.html { redirect_to posts_path }
format.js
else
flash[:notice] = "Message failed to save."
format.html { redirect_to posts_path }
end
end
end
end
and corresponding to this I have written the following test case :-
require 'spec_helper'
describe PostsController do
describe "GET 'index'" do
it "returns http success" do
get 'index'
response.should be_success
end
end
describe "#create" do
it "creates a successful mesaage post" do
#post = Post.create(message: "Message")
#post.should be_an_instance_of Post
end
end
end
I am getting failures on both. Please take a look on the code and help me figure out.
I suspect you are not logged in since you are using Devise?
Maybe you need to include the devise testhelpers:
describe PostsController do
include Devise::TestHelpers
before(:each) do
#user = User.create(...)
sign_in #user
end
#assertions go here
end
As Tigraine states, it appears as though you probably are not logged in (with Devise) when the tests get executed. However, showing the failures would help in narrowing down the problem further.
On top of that, the second test isn't really an integration test and I would probably prefer something like the following to test the same condition. There are two types of test you could do:
# inside 'describe "#create"'
let(:valid_params) { {'post' => {'title' => 'Test Post'} }
it 'creates a new Post' do
expect {
post :create, valid_params
}.to change(Post, :count).by(1)
end
# and / or
it 'assigns a new Post' do
post :create, valid_params
assigns(:post).should be_a(Post)
assigns(:post).should be_persisted
end
Don't forget to add this line into your spec_helper.rb
require "devise/test_helpers"
include Devise::TestHelpers
Nevertheless, here is link for Devise wiki - How to test Controllers where you can find more info about this approach. I recommend writing the before method without (:each), what I remember it sometimes causes problems.
before do
#user = FactoryGirl.create(:user)
sign_in #user
end
Can always use:
puts response.inspect
To see how your response looks like.

Resources