Tests are not passing - ruby-on-rails

I'm using RSpec for tests and I don't know how to get this to green.
In this case, I have a model called "PartType" that holds an attribute called "quotation".
The value for quotation comes from a form, so it will be a string.
To demonstrate you can go to console and type:
(1..1000).includes?("50") # false
but..
(1..1000).includes?(50) # true
And this value can have decimals. So I needed to do a "type_cast".
I have this on my PartTypemodel:
before_validation :fix_quotation, :if => :quotation_changed?
protected
def fix_quotation
self[:quotation] = quotation_before_type_cast.tr(' $, ' , '.' )
end
This are working as expected BUT when go to tests, it fails.
Here is my part_type_spec.rb:
require 'spec_helper'
describe PartType do
before(:each) do
#attr = { :title => "Silver", :quotation => 100 }
end
it "should create a instance given a valid attributes" do
PartType.create!(#attr)
end
it "should accept null value for quotation" do
PartType.new(#attr.merge(:quotation => nil)).should be_valid
end
it "should accept 0 value for quotation" do
PartType.new(#attr.merge(:quotation => 0)).should be_valid
end
end
And finally the failing tests:
Failures:
1) PartType should create a instance given a valid attributes
Failure/Error: PartType.create!(#attr)
NoMethodError:
undefined method tr' for 100:Fixnum
# ./app/models/part_type.rb:7:infix_quotation'
# ./spec/models/part_type_spec.rb:10:in `block (2 levels) in '
2) PartType should accept 0 value for quotation
Failure/Error: PartType.new(#attr.merge(:quotation => 0)).should be_valid
NoMethodError:
undefined method tr' for 0:Fixnum
# ./app/models/part_type.rb:7:infix_quotation'
# ./spec/models/part_type_spec.rb:18:in `block (2 levels) in '
Finished in 0.06089 seconds
3 examples, 2 failures

Your include? snippets are wrong, I got false in the first, true in the second.
before_validation is executed and quotation_before_type_cast is expected to be a String but it is a Fixnum. Change 100 to '100' and 0 to '0'.

Related

Date.today.to_s(:long) not converting to string

I am working on an assignment and I have written the following method based on our instructions:
def create_todolist(params)
due_date = Date.today.to_s(:long)
TodoList.create(list_name: params[:name],list_due_date: params[:due_date])
end
But when I run the rspec test, I get the following error:
1) Assignment rq03 rq03.2 assignment code has create_todolist method should create_todolist with provided parameters
Failure/Error: expect(testList.list_due_date).to eq due_date
expected: Thu, 07 May 2020
got: "2020-05-07"
(compared using ==)
Diff:
## -1,2 +1,2 ##
-Thu, 07 May 2020
+"2020-05-07"
# ./spec/assignment_spec.rb:177:in `block (4 levels) in <top (required)>'
# ./spec/assignment_spec.rb:14:in `block (2 levels) in <top (required)>'
Here is the rspec test:
context "rq03.2 assignment code has create_todolist method" do
it { is_expected.to respond_to(:create_todolist) }
it "should create_todolist with provided parameters" do
expect(TodoList.find_by list_name: "mylist").to be_nil
due_date=Date.today
assignment.create_todolist(:name=> 'mylist', :due_date=>due_date)
testList = TodoList.find_by list_name: 'mylist'
expect(testList.id).not_to be_nil
expect(testList.list_name).to eq "mylist"
expect(testList.list_due_date).to eq due_date
expect(testList.created_at).not_to be_nil
expect(testList.updated_at).not_to be_nil
end
end
At first I had just due_date = Date.today and was getting the same error and I'm not sure how to fix it. I'm wondering if it is because I am using a different version of ruby/rails than what was used when the course was created ( 5 years ago -_-).
Any help would be greatly appreciated!
Thank you :)
You are trying to compare a Date object:
due_date = Date.today
With a string object you generated while you created your record:
Date.today.to_s(:long)
As you can see, these are different types of objects:
Date.today.to_s(:long)
=> "May 07, 2020"
Date.today.to_s(:long).class
=> String
Date.today
=> 2020-05-07
Date.today.class
=> Date
Date.today.to_s(:long) == Date.today
=> false
I figured it out. When I was creating the TodoLists table, I didn't specify the migration type as :date. so by default, due_date was set to be a string. So I set to type :date and changed due_date to equal:
due_date = Date.today
Thank you for taking the time to help me out :)

post command not rendering data in Rspec

I have defined a controller Add. In controller i have defined a function (add_params)
def add_values
ans = params[:first_element] + params[:second_element]
render :json => {:result => ans}.to_json
end
in routes file i have declared post :add_params
if i call curl -X POST -H "Content-Type:application/json" -d '{"first_element" : 3, "second_element" :2}' http://localhost:8000/add/add_values it return {"result":5}
but when i tried to test in Rspec as
describe AddController, :type => :request do
it "must return 5" do
post "http://localhost:8000/add/add_values", {"first_element" : 3, "second_element" :2}.to_json
expect(JSON.parse(response.body)["result"]).to eq "5"
end
end
it gives error as
Failure/Error: expect(response["result_is"]).to eq 5
expected: 5
got: nil
(compared using ==)
# ./spec/controller/add_controller_spec.rb:67:in `block (2 levels) in <top (required)>'
i am using rails 3.2.16 , ruby 2.1.5 , rspec 3.0.0
Is pretty weird that you receive
Failure/Error: expect(response["result_is"]).to eq 5
if your expectation is
expect(JSON.parse(response.body)["result"]).to eq "5"
the parameters of expect function are different one each other.
You should receive an error like this
Failure/Error: expect(JSON.parse(response.body)["result_is"]).to eq "5"
Are you sure your expectation is not
expect(response["result_is"]).to eq 5
?

Rspec testing validation

I am new to rails and I'm trying to understand testing using Rspec. I created a simple model (just for testing purposes) named Contact that contains firstname:string, lastname:string and email:string. I am just trying to set a test for firstname to fail if is empty.
my Rspec test is as follow:
describe Contact do
it "creates a valid model" do
contact = Contact.new(
firstname: 'firstname',
lastname: 'lastname',
email: 'email'
)
expect(contact).to be_valid
end
it "is invalid without a firstname" do
contact = Contact.new(firstname: nil)
contact.valid?
expect(contact.errors[:firstname]).to include("can't be blank")
end
My understanding is that this test should not return any failures but it does. Output below:
Failures:
1) Contact is invalid without a firstname
Failure/Error: expect(contact.errors[:firstname]).to include("can't be blank")
expected [] to include "can't be blank"
# ./spec/models/contact_spec.rb:16:in `block (2 levels) in <top (required)>'
Finished in 0.11659 seconds (files took 2.39 seconds to load)
18 examples, 1 failure, 15 pending
Failed examples:
rspec ./spec/models/contact_spec.rb:13 # Contact is invalid without a firstname
If I change the expect statement from ".to" to "not_to" the test passes, so I think I am getting this backwards, any help or explanation is greatly appreciated.
As smathy said in the comments, I forgot to include the validation inside my model. That solved my problem.

RSPEC - Expected vs Received Error

Here is my test:
describe Item do
subject {Item.new(:report_id => 26 , :name => 'Gas' , :tax_rate => 0.13, :tax_id => 1 , :category_id => 15 , :sub_category_id => 31 , :job_id => 1 , :total => 20 )}
let(:tax) {Tax.where(id: subject.tax_id).first}
let(:sub_category) {SubCategory.where(id: subject.sub_category_id).first}
it 'Calculate with just Total' do
subject.name.should be == 'Gas'
tax = Tax.find_by_id(subject.tax_id)
subject.sub_category_id.should be == 31
subject.set_nil_values
sub_category.should_receive(:taxable).and_return(1)
tax.should_receive(:rate).and_return(0.13)
sub_category.should_receive(:tax_adjustment).and_return(nil)
subject.should_receive(:tax_rate).and_return(0.13)
subject.calculate_tax(tax, sub_category)
subject.tax_amount = (((subject.total - subject.deduction) - ((subject.total - subject.deduction) / (1 + 0.13))) * 1)
subject.calculate_cost
subject.cost.should be_within(0.01).of(17.70)
end
Here is my error:
1) Item Calculate with just Total
Failure/Error: subject.should_receive(:tax_rate).and_return(0.13)
(#<Item:0x007faab7299c30>).tax_rate(any args)
expected: 1 time with any arguments
received: 3 times with any arguments
# ./spec/models/item_spec.rb:25:in `block (2 levels) in <top (required)>'
I did some research, and tried to use this instead:
expect_any_instance_of(subject).to receive(:tax_rate)
But now get the following error:
1) Item Calculate with just Total
Failure/Error: expect_any_instance_of(subject).to receive(:tax_rate)
NoMethodError:
undefined method `method_defined?' for #<Item:0x007fe6fdaa1bf8>
# ./spec/models/item_spec.rb:25:in `block (2 levels) in <top (required)>'
Your initial error occurred because, as the error message stated, the method in question was called three times rather than once, which is the implicit expectation. Assuming the actual behavior is what it should be, you can change the expectation to be:
...receive(...).exactly(3).times
See http://rubydoc.info/gems/rspec-mocks/frames for more info.
As for the second error you encountered, based on my testing, this occurs when you use expect_any_instance_of with a class that already has an instance stubbed and then you call that stubbed instance. In any event, even if this had worked, I don't believe it's what you would have wanted, as the semantics in terms of frequency of expect_any_instance_of is the same as expect, namely "one (total) call across the stubbed instance(s)".
If this second error occurred without you having removed the existing expectation on subject, let me know.

Rails nested models failing validation

I'm writing model spec tests using rspec for nested models 3 levels deep. Each -> represents a has_many relationship.
Users->Goals->Milestones
Right now, my spec/models/milestone_spec.rb test is failing a be_valid check, and I'm a little stumped as to why this is happening.
Failures:
1) Milestone
Failure/Error: it { should be_valid }
expected valid? to return true, got false
# ./spec/models/milestone_spec.rb:17:in `block (2 levels) in <top (required)>'
The spec itself:
describe Milestone do
let(:user) { FactoryGirl.create(:user) }
let(:goal) { user.goals.build(content: "Loreum Ipsum", amount: "30", interval: 2) }
before do
#milestone = goal.milestones.build(amount: "20")
end
subject { #milestone }
it { should respond_to(:goal_id) }
it { should respond_to(:amount) }
# not sure why this isn't working
it { should be_valid }
Could it be with how I'm creating the #milestone? I've tried goal.milestones.new, and that doesn't seem to make a difference. Below in the spec I have some tests for fields properly validating, and those run fine.
Any ideas?
Try this:
it "should be valid" do
#milestone.valid?
puts #milestone.errors.full_messages
end
That will run the validations and print out the the validation errors for you so you can see what's going on.

Resources