I'm ashamed to make this question but I can't find my error, I am once again doing the rails tutorial from Michael Hartl, since the first time I wasn't able to do the proper TDD, anyways I have managed to have working every single test but one! the thing is that I test it manually on rails' console and it worked, I tried to reset the db with rake db:reset and rake test:prepare and obviously re-populating the db rake db:populate ok, straight to the point... I have the following test
describe "status" do
let(:unfollowed_posts) do
FactoryGirl.create(:micropost, user: FactoryGirl.create(:user))
end
let(:followed_user) { FactoryGirl.create(:user) }
before do
#user.follow!(followed_user)
3.times { followed_user.microposts.create!(content: "Lorem Ipsum") }
end
its (:feed) { should include(newer_micropost) }
its (:feed) { should include(older_micropost) }
its (:feed) { should_not include(unfollowed_posts) }
its (:feed) do
followed_user.microposts.each do |micropost|
should include(micropost)
end
end
end
according to me, everything is ok, I test it manually on rails console, however when runing the spec with rpsec spec/models/user_spec.rb it comes up with the following error
Failures:
1) User micropost associations status feed
Failure/Error: should include(micropost)
expected #<ActiveRecord::Relation [#<Micropost id: 355, content: "Lorem ipsum", user_id: 702, created_at: "2014-05-10 03:34:47", updated_at: "2014-05-10 04:34:47">, #<Micropost id: 354, content: "Lorem ipsum", user_id: 702, created_at: "2014-05-09 04:34:47", updated_at: "2014-05-10 04:34:47">]> to include #<Micropost id: 358, content: "Lorem ipsum", user_id: *703*, created_at: "2014-05-10 04:34:47", updated_at: "2014-05-10 04:34:47">
Diff:
## -1,2 +1,3 ##
-[#<Micropost id: 358, content: "Lorem ipsum", user_id: *703*, created_at: "2014-05-10 04:34:47", updated_at: "2014-05-10 04:34:47">]
+[#<Micropost id: 355, content: "Lorem ipsum", user_id: 702, created_at: "2014-05-10 03:34:47", updated_at: "2014-05-10 04:34:47">,
+ #<Micropost id: 354, content: "Lorem ipsum", user_id: 702, created_at: "2014-05-09 04:34:47", updated_at: "2014-05-10 04:34:47">]
</code>
I don't understand why the user_id is changed if the code 3.times { followed_user.microposts.create!(content: "Lorem Ipsum") } doesn't touch followed_user at all, so... that's my headache now, why is this happening? is it a bogus behavior on rspec, thanks in advance, and sry for this dull question.
you need to change you feed method in user.rb file
from
def feed
Micropost.where("user_id = ?", user)
end
to
def feed
Micropost.from_users_followed_by(self)
end
as well as add method self.from_users_followed_by to your micropost.rb file
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id"
where("user_id IN (#{followed_user_ids}) or user_id = :user_id", user_id: user.id)
end
Related
I have an endpoint the returns all the comments on a blog. I would like to have the name of the user that made the comment. Is there a way to bring it all together when hitting that comments endpoint or do I have to make another query for each comment?
def comments
#comments = #blog.comments
render json: { comments: #comments }
end
This is what doing #blog.comments returns
[#<Comment id: 1, content: "This is a very good post", created_at: "2020-09-11 01:55:56", updated_at: "2020-09-11 01:55:56", blog_id: 3, user_id: 1>, #<Comment id: 2, content: "I agree with all of this", created_at: "2020-09-11 01:55:56", updated_at: "2020-09-11 01:55:56", blog_id: 3, user_id: 1>, #<Comment id: 3, content: "I don't agree with all of this", created_at: "2020-09-11 01:55:56", updated_at: "2020-09-11 01:55:56", blog_id: 3, user_id: 1>]>
Assuming you have a users table with a field users.name, and a belongs_to :user relationship on your model comment:
Just replace the line
#comments = #blog.comments
with
#comments = #blog.comments.select('comments.*, users.name').joins(:user)
I'm not very sure I'm doing it right, but I have two models: House that has_one Address.
The Address model has:
class Address < ApplicationRecord
searchkick
belongs_to :house
end
I'm trying to test my house_controller with RSpec like this
RSpec.describe HousesController do
context 'GET #index' do
before { get :index }
it { is_expected.to render_template('index') }
it 'assigns #houses' do
h = create(:house)
expect(assigns(:houses).results).to eq([h])
end
...
Nevertheless I always get a result which is not the one I expect.
The code of my controller is the following:
def index
if params[:term].present?
#houses = House.search(params[:term])
else
#houses = House.search('*')
end
end
I'm not sure I understand it, but could it be that since I'm using FactoryBot, it is creating lots of houses, and then when getting in the index method, there's a bunch of houses there and not only and precisely h?
This is my failure:
Failures:
1) HousesController GET #index assigns #houses
Failure/Error: expect(assigns(:houses).results).to eq([h])
expected: [#<House id: 763, rent: 1173, deposit: 739, description: "Rerum cado curso curo alias.", preferred_ge...2018-11-26 21:40:43", available_at: "2018-12-17", user_id: 15945, lease_length: nil, built_in: nil>]
got: [#<House id: 215, rent: 0.839e3, deposit: 0.797e3, description: "Rerum aeneus taceo crepusculum aestu...2018-11-26 21:17:53", available_at: "2018-12-17", user_id: 15776, lease_length: nil, built_in: nil>]
(compared using ==)
Diff:
## -1,2 +1,5 ##
-[#<House id: 763, rent: 1173, deposit: 739, description: "Rerum cado curso curo alias.", preferred_gender: 0, created_at: "2018-11-26 21:40:43", updated_at: "2018-11-26 21:40:43", available_at: "2018-12-17", user_id: 15945, lease_length: nil, built_in: nil>]
+[#<House id: 215, rent: 0.839e3, deposit: 0.797e3, description: "Rerum aeneus taceo crepusculum aestus.", preferred_gender: 0, created_at: "2018-11-25 12:50:11", updated_at: "2018-11-25 12:50:11", available_at: "2018-12-16", user_id: 8065, lease_length: nil, built_in: nil>,
+ #<House id: 235, rent: 0.519e3, deposit: 0.642e3, description: "Cicuta totidem arbustum arcesso fugit tego.", preferred_gender: 0, created_at: "2018-11-25 12:54:28", updated_at: "2018-11-25 12:54:28", available_at: "2018-12-16", user_id: 8085, lease_length: nil, built_in: nil>,
+ #<House id: 648, rent: 0.668e3, deposit: 0.1104e4, description: "Corporis tametsi demens.", preferred_gender: 0, created_at: "2018-11-26 21:17:43", updated_at: "2018-11-26 21:17:43", available_at: "2018-12-17", user_id: 15775, lease_length: nil, built_in: nil>,
+ #<House id: 649, rent: 0.799e3, deposit: 0.611e3, description: "Ut ancilla tredecim.", preferred_gender: 0, created_at: "2018-11-26 21:17:53", updated_at: "2018-11-26 21:17:53", available_at: "2018-12-17", user_id: 15776, lease_length: nil, built_in: nil>]
# ./spec/controllers/houses_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
I'm starting with RSpec now and it's really taking me effort and hours to try to grab the grasp of it, thanks a lot in advance!
Searchkick docs about disabling indexing for tests with RSpec.
You don't want to be updating your objects in Elasticsearch always while running tests. You want to do it only when you'll be explicitly testing your search functionality (or indexing/deleting from index). To do so, you will have to disable searchkick callbacks, define a custom tag for your tests and enable indexing only for these tests. You may have to handle cleaning your index after a test/groups of tests as well.
#vich's point is also important, you currently create your object too late, after the request.
I would change your setup to:
context 'GET #index', :search do
let!(:house) { create(:house) }
before { get :index }
it 'assigns #houses' do
expect(assigns(:houses).results).to eq([house])
end
end
Try creating your house in the before block:
context 'GET #index' do
before do
let!(:house) { create(:house) }
get :index
end
it { is_expected.to render_template('index') }
it 'assigns #houses' do
expect(assigns(:houses).results).to eq([house])
end
end
A couple of things to note:
As opposed to let, let! is immediately invoked (thus creating your record before the index action is hit)
Add a breakpoint (IDE) or use a debugger (byebug, pry, etc.) and put it before the get :index call to see what (if any) houses already exist.
require 'rails_helper'
feature "comment" do
given(:current_user) do
create(:user)
end
given(:undertaking) do
create(:undertaking)
end
background do
login_as(current_user)
end
scenario "can create comment" do
#below two because undertaking = user_id:2 & asking_id:1
create(:user)
create(:asking)
p undertaking
p Asking.find(1)
p User.find(2)
p User.find(1)
p Undertaking.all
visit undertaking_path(undertaking)
expect(current_path).to eq undertaking_path(1)
within("form#undertake-form-test") do
fill_in "content" , with: "heyheyhey"
end
click_button 'Send'
expect(page).to have_content 'heyheyhey'
end
end
This is spec/features/comment_spec.rb.
and this below is result command rspec.
#<Undertaking id: 1, title: "MyString", content: "MyText", result: false, user_id: 2, asking_id: 1, created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08">
#<Asking id: 1, content: "MyText", fromlang: "MyString", tolang: "MyString", usepoint: 1, finished: false, title: "MyString", deadline: nil, user_id: 1, created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08">
#<User id: 2, email: "shiba.hayato2#docomo.ne.jp", created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08", provider: nil, uid: nil, name: "Shiruba", occupation: "大学生", age: 10, sex: "男性", content: "heyheyheyeheyeheye", skill: "日本語検定3級", picture: "/assets/default_user.jpg", point: 500, country: "Japan", language1: "Japanese", language2: "Korea", language3: "English">
#<User id: 1, email: "shiba.hayato1#docomo.ne.jp", created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08", provider: nil, uid: nil, name: "Shiruba", occupation: "大学生", age: 10, sex: "男性", content: "heyheyheyeheyeheye", skill: "日本語検定3級", picture: "/assets/default_user.jpg", point: 500, country: "Japan", language1: "Japanese", language2: "Korea", language3: "English">
#<ActiveRecord::Relation [#<Undertaking id: 1, title: "MyString", content: "MyText", result: false, user_id: 2, asking_id: 1, created_at: "2016-12-13 15:07:08", updated_at: "2016-12-13 15:07:08">]>
F
Failures:
1) comment can create comment
Failure/Error: <%= #undertaking.id %>
ActionView::Template::Error:
undefined method `id' for nil:NilClass
and this below is undertaking_controller.rb.
class UndertakingController < ApplicationController
def show
#undertaking=Undertaking.find(params[:id])
#comment=Comment.new do |c|
c.user=current_user
end
end
end
and this below is undertaking/show.html.erb.
<%= #undertaking.id %>
Why do I have the error? Why #undertaking is nil in view although Undertaking.first is not nil in spec/features/comment_spec.rb?Please help me.
I think it has to do with the naming used for your controller . The convention is undertakings/show.html.erb for the view instead of undertaking/show.html.erb . I would also use
class UndertakingsController < ApplicationController
instead of
class UndertakingController < ApplicationController
Finally I would check that all my routes also have the correct naming. Hope that helps. Good luck
I am trying to test the following controller action(Using Ruby on Rails, RSPEC, and FactoryGirl):
class ContactsController < ApplicationController
before_action :authenticate_user!
def index
#contacts = current_user.contacts
# #contacts = Contact.all
end
Here is my contacts_controller_spec.rb file:
require 'rails_helper'
describe ContactsController do
before do
#user = FactoryGirl.create(:user_with_contacts)
sign_in #user
end
describe "GET INDEX" do
it "assigns #contacts" do
expect(assigns(:contacts)).to eq(#user.contacts)
end
end
Failure/Error: expect(assigns(:contact)).to eq([contact])
expected: [#<Contact id: 295, first_name: "Loy", email: "leon#hegmannhintz.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Wyman", user_id: 343>]
got: #<Contact id: nil, first_name: nil, email: nil, phone_number: nil, created_at: nil, updated_at: nil, last_name: nil, user_id: nil>
And here is my users_spec.rb file:
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
password { "32423fdsfasf42" }
factory :user_with_contacts do
transient do
contacts_count 2
end
after(:create) do |user, evaluator|
create_list(:contact, evaluator.contacts_count, user: user)
end
end
end
end
Any Help please? I have been stuck on this for a long time.
If i call
puts #user.inspect
I get
#<User id: 340, email: "johnson_kaulke#brekke.com", encrypted_password: "$2a$04$Si5k6Q1eYERvhQITXKBoIOGEzPyK50E3IQ.yjRcqmDj...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42">
and
calling
puts #user.contacts.inspect
I get
#<ActiveRecord::Associations::CollectionProxy [#<Contact id: 289, first_name: "Fae", email: "ariane#johnston.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Spinka", user_id: 340>, #<Contact id: 290, first_name: "Marcellus", email: "chloe_deckow#buckridge.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Bashirian", user_id: 340>]>
Its just when i call the assigns(:contacts) that the problem happens!
I think you forgot to invoke the controller action. :)
Try adding get :index
it "assigns #contacts" do
get :index
expect(assigns(:contacts)).to eq(#user.contacts)
end
I am only familiar with Rspec, but now I need to fix a library which uses Test::Unit.
I find out that when I reload the record, the association becomes nil
For example:
test "accepts nested attributes from subscription to user ()" do
#user = User.create(name:'Ash')
#subscription = #user.create_subscription()
puts "user: " << #user.inspect
puts "subscription: " << #user.subscription.inspect
#subscription.update_attributes({ :user_attributes => { :notification_comment => true } })
#user.reload
puts "user: " << #user.inspect
puts "subscription: " << #user.subscription.inspect
assert #user.subscription, "should have an subscription"
end
Outputs:
user: #<User id: 815823837, account_id: nil, name: "Ash", email: nil, settings: {}, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
subscription: #<Subscription id: 1, user_id: 815823837, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
user: #<User id: 815823837, account_id: nil, name: "Ash", email: nil, settings: {}, created_at: "2013-02-07 04:28:51", updated_at: "2013-02-07 04:28:51">
subscription: nil
Why does this happen? I did check and I can confirm that I can Subscription.find(#subscription.id) so it is saved in the database.