How to test the eq of a .rjust 8, "0" with rspec - ruby-on-rails

I have a little function to make a customer_nr with
id.to_s.rjust 8, "0"
This gives me a 8 diget number with the id and before filled with 0 until I have 8 diggets.
How can I test this with rspec? The first test works, but the second on is wrong since the id is interactive. Any Idea how to test the eq? FactoryGirl creates a user with FactoryGirl.create(:user). This works if the created user gets an single digget id.
When it gets a more diggets id then the test fails.
Like expected: "00000002398" got: "00002398"
describe "#customer_nr" do
it "should have 8 digits" do
user.customer_nr.length.should eq 8
end
it "should use the user_id" do
user.customer_nr.should eq "0000000#{user.id}"
end
end
best regard
denym

After my comment and your edit issue is easy. Everything is correct but your user have id 2398. You can make test in irb
2398.to_s.rjust 8, "0"
give exactly what test return. In test your db created records and destroy after tested but id still increment. You can make:
user.customer_nr.should eq "0000000#{user.id}".split(//).last(8).join
or like toro2k wrote in his comment.

Related

Testing an update operation in RSpec, evaluates to true, but test fails?

I have this test:
it "saves the notification id in the referral for future reference" do
expect { subject.perform(*args) }
.to change(referral, :notification_id).from(nil).to(customer_notification_delivery.id)
end
And the code that it runs on top is:
if notification.present?
referral.update(friend_customer_notification_delivery_id: notification.id)
end
I added a few debug messages, to check on them after firing the test, to ensure that this condition was being met, and the code was being run, and I got true for both
p notification.present?
p referral.update(friend_customer_notification_delivery_id: customer_notification_delivery.id)
Anything I am missing? Why the update returns true, but the value is not getting updated on the test?
The output I get:
expected #notification_id to have changed from nil to 5, but did not change
referral in your test and referral in your object-under-test are two different objects, I'm willing to bet. Changes to one do not affect the other. referral in the test does not magically pull up updates from the related database record made by some other code.
I normally do it like this
it "saves the notification id in the referral for future reference" do
expect { subject.perform(*args) }
.to change{ referral.reload.notification_id }.from(nil).to(customer_notification_delivery.id)
end

RSpec do not see updated attributes in factory_bot object

I have report object called SiegeReport, that makes some calculations and returns integer object. When there is no warrior in the building, then siege_ability equals 0. The code itself is not important here, because it works fine in console and in application. Factories made by factory_bot work ok in all the other examples. I just have problem with testing the method:
require 'rails_helper'
RSpec.describe Reports::SiegeReport do
subject(:siege_report) { Reports::SiegeReport.new(building: building).call }
let(:building) { create(:building, granary: 100) }
let(:clan) { create(:clan) }
context 'with 1 infantry' do
let(:warrior) { create(:warrior, clan_id: clan.id, building_id: building.id) }
it 'returns 9' do
expect(siege_report).to eq(9)
end
end
end
RSpec returns:
Reports::SiegeReport siege ability with 1 infantry returns 9
Failure/Error: expect(siege_report).to eq(9)
expected: 9
got: 0
(compared using ==)
I checked it with pry and warrior object is valid, even building.warriors returns warrior, but in attributes number of warriors is still 0. The very same example works when i type it manually in console. How can I make RSpec update building attributes before testing?
Ok, I found solution but is really not elegant:
it 'returns 9' do
warrior.save
expect(siege_report).to eq(9)
end
It works but it seems to me that it is not the proper way of testing. Still, I can't find a better solution.

Expecting string but getting nil in Rspec test

I am working on a Ruby problem called "Speaking Grandma" where I need to create a method that should should take in a string argument containing a phrase and check to see if the phrase is written in all uppercase: if it isn't, then grandma can't hear you. She should then respond with (return) HUH?! SPEAK UP, SONNY!.
However, if you shout at her (i.e. call the method with a string argument containing a phrase that is all uppercase, then she can hear you (or at least she thinks that she can) and should respond with (return) NO, NOT SINCE 1938!.
I wrote the following code:
def speak_to_grandma(input)
if
input != input.upcase
puts 'HUH?! SPEAK UP, SONNY!'
else
puts 'NO, NOT SINCE 1938!'
end
end
When I run RSpec, I fail both tests. It gives the following message:
Failure/Error: expect(speak_to_grandma('Hi Nana, how are you?')).to eq 'HUH?! SPEAK UP, SONNY!'
expected: "HUH?! SPEAK UP, SONNY!"
got: nil
and
Failure/Error: expect(speak_to_grandma('WHAT DID YOU EAT TODAY?')).to eq "NO, NOT SINCE 1938!"
expected: "NO, NOT SINCE 1938!"
got: nil
(compared using ==)
I have no idea what I am doing wrong here. Can anyone help?
The speak_to_grandma method returns the return value of the puts method, being the last line in the method. The return value of puts is nil(Why are all my puts returning =>nil?)
The eq method in Rspec checks the return value of a method. The string is output to the screen with puts, but the return value is nil, and that's what Rspec is checking for.
If you remove puts, the tests should pass, because the string will be the return value of the method. But the correct way would be to test it with the output method in Rspec. Write your test like this:
expect { speak_to_grandma('WHAT DID YOU EAT TODAY?') }.to output("NO, NOT SINCE 1938!").to_stdout

Basic RSpec issue - method runs but tests fail

Given all the hype over TDD, I decided it was time to dig in and add that to the list of things to study. I'm running into an issue, and I'm 100% certain it's just a function of something being wrong with my tests in RSpec. I'm still brand new to RSpec, so I'm having trouble figuring it out... my method works just fine, but the test for the method does not.
Method Code (I know I can refactor this A LOT. This is one of the first Ruby programs I wrote awhile back, which explains the ugliness)
def caesar_cipher(string,offset)
string=string.to_s
offset=offset.to_i
cipher=[]
string.each_byte do |i|
#capital letters
if (i>64 && i<91)
if (i+offset)>90
cipher << (i+offset-26).chr
else
cipher << (i+offset).chr
end
elsif (i>96 && i<123)
if (i+offset)>122
cipher << (i+offset-26).chr
else
cipher << (i+offset).chr
end
else
cipher << i.chr
end
end
cipher=cipher.join('')
puts "The encrypted string is: #{cipher}"
end
puts "Enter the string you'd like to encrypt"
string=gets.chomp
puts "Enter the offset you'd like to use"
offset=gets.chomp
caesar_cipher(string,offset)
Test Code (Just for one generic case, all lower case input)
require './caesarCipher.rb'
describe "caesar_cipher" do
it 'should handle all lower case input' do
caesar_cipher("abcdefg", 3).should == "defghij"
end
end
Method output:
$ ruby caesarCipher.rb
Enter the string you'd like to encrypt
abcdefg
Enter the offset you'd like to use
3
The encrypted string is: defghij
Test Output:
$ rspec spec/caesar_cipher_spec.rb
Enter the string you'd like to encrypt
Enter the offset you'd like to use
The encrypted string is: require './caesarCipher.rb'
The encrypted string is: defghij
F
Failures:
1) caesar_cipher should handle all lower case input
Failure/Error: caesar_cipher("abcdefg", 3).should == "defghij"
expected: "defghij"
got: nil (using ==)
# ./spec/caesar_cipher_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00542 seconds (files took 0.14863 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/caesar_cipher_spec.rb:4 # caesar_cipher should handle all lower case input
Any help on why the tests are failing? Judging by the output it looks like it's running it twice or something in the tests.
Add cipher or return cipher after this line
puts "The encrypted string is: #{cipher}"
And it should work
To explain the fix given, the last expression in a method is the return value. You've passed the value to STDOUT but not as the return value of the method, so RSpec was failing.

Class methods and expect argument

I have simple test case: (board has_many links, link belongs_to board)
context "with feeds" do
let (:board) {FactoryGirl.create(:board_tree)}
it "returns links from all feeds" do
expect(board.all_links.count).to eq Link.all.count
end
end
It fails (expected 8 got 2) - which is ok, I expected the same.
Now I switch this expect with:
expect(Link.all.count).to eq board.all_links.count
This time I thought it will fail with expected 2 got 8, but instead of it I get: expected 2, got 0.
Any idea why? For me both expectations should be equal.
If you try changing:
let (:board) {FactoryGirl.create(:board_tree)}
into
let! (:board) {FactoryGirl.create(:board_tree)}
you will see that the results won't change when you invert the conditions. The problem is that links are created by rspec the first time that the board variable is referenced, so in the second example, there are no links yet when rspec is evaluating the expect(Link.all.count) part.

Resources