How to check the assignment of an instance variable in a new action of my controller using rspec?

I am new to testing and I have a UserController that I want to test. I start with a new action and still have the following:

require 'spec_helper' describe UsersController do describe "GET 'new'" do it "assigns a new User to @user" do user = User.new get :new assigns(:user).should eq(user) end it "renders the :new template" end end 

My UserController so far looks like

 class UsersController < ApplicationController def new @user = User.new end end 

I expected my first test to work, but when I run it, I get the following:

 Failures: 1) UsersController GET 'new' assigns a new User to @user Failure/Error: assigns(:user).should eq(user) expected: #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil> got: #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil> (compared using ==) Diff:#<User:0x007fe4bbfceed0>.==(#<User:0x007fe4bce5c290>) returned false even though the diff between #<User:0x007fe4bbfceed0> and #<User:0x007fe4bce5c290> is empty. Check the implementation of #<User:0x007fe4bbfceed0>.==. # ./spec/controllers/users_controller_spec.rb:9:in `block (3 levels) in <top (required)>' 

A game in the console shows the following:

 irb(main):001:0> a = User.new => #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil> irb(main):002:0> b = User.new => #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil> irb(main):003:0> a == b => false 

So now I'm curious why the 2 empty ActiveRecord objects are not equal (after all, Array.new == Array.new returns true) and what I need to do to pass the test.

+6
source share
2 answers

You should probably change your test to something like this:

 describe UsersController do describe "GET 'new'" do it "assigns a new User to @user" do get :new assigns(:user).should be_new_record assigns(:user).kind_of?(User).should be_true end it "renders the :new template" end end 

And you will have the same effect. If two objects are not stored, they do not have primary keys, since Rails will use the object_id equality to compare them, so they are not == .

+6
source

Activerecord interaction mainly deals with whether two objects correspond to the same database row (for example, two instances corresponding to the same row are equal, even if you start changing the attributes of one of them).

If you call User.new twice and save each object, you will have 2 different rows in the database. Therefore, it makes sense to me that they should not be equal.

In terms of your test, you can do 2 things. One of them is to verify that the designated user is a user and that he is unsaved.

Another way is something like strings

 User.should_receive(:new).and_return(@user) get :new assigns(:user).should == @user 
+1
source

Source: https://habr.com/ru/post/917295/


All Articles