Reputation: 19
I am a ruby newbie, I have managed to pull out the code for ruby but writing rspecs for them seems problematic. It's hard to understand the way to write rspecs even after reading few tutorials. Someone please help me to write for an input method then I would try to refactor it for the rest.
RB file:
module RubyOperations
class Operations
def input(num)
RubyOperations.log('Enter a number:[Between 1 to 10]',:BOTH)
num = Integer(gets.chomp)
raise StandardError if num <= 0 || num > 10
return num
rescue StandardError, ArgumentError => e
RubyOperations.log(e,:ERROR)
end
end
end
RSPEC:
describe 'RubyOperations' do
describe 'Operations' do
describe '.input' do
context 'when number is provided' do
it 'returns the number provided' do
expect(RubyOperations.input(num)).to eq(Integer)
end
end
end
end
end
Upvotes: 0
Views: 5658
Reputation: 337
There are few issues with code that you have shared:
1) In the Operations
class, the method input
receives an argument which is not used anywhere because of this line: num = Integer(gets.chomp)
. Basically gets
is the method that waits for user input, and the assignment num = ...
overrides the value of argument (num
) that is passed into the method, hence it is pointless to pass num
argument into the method.
2) In your spec sample you call input
method on RubyOperations
module, while the input
lives in class Operations
under namespace RubyOperations
. Also method input
is not a class method but instance method. So proper method call would be: RubyOperations::Operations.new.input(5)
3) To run a spec for input
method you would need to stub user input. RSpec-mocks gem can help you with that - https://github.com/rspec/rspec-mocks. It has allow
stub method: allow(object).to receive(:gets) { "5" }
The whole sample will be:
it 'returns the number provided' do
# instantiate object that we will test
subject = RubyOperations::Operations.new
# we stub method 'gets' and whenever it is called we return string "5"
allow(subject).to receive(:gets) { "5" }
# we call method input with argument 1, the argument 1 is pointless as described in point 1) and can be omitted
expect(subject.input(1)).to eq(5)
end
Upvotes: 0
Reputation: 3605
You can check the class of the output of the method to equal integer
require 'ruby_final_operations'
describe 'RubyOperations' do
describe 'Operations' do
describe '.input' do
context 'when number is provided' do
it 'returns the number provided' do
expect(RubyOperations.input(num).class).to eq(Integer)
(or)
expect(RubyOperations.input(num)).to be_a_kind_of(Integer)
end
end
end
end
end
And whenever you write rspec keep in mind
If the method for which you are writing rspec deals with manipulations in your db then check if db is manipulated or not
Or if you are writing rspec for any methods which returns an object then procced like this
if a method is defined like
def square_of_a_number(num)
num*num
end
Then write rspec like this
it 'returns square of a number' do
expect(square_of_a_number(2).to eq(4)
end
For any methods that you know the output of a method will be that then hardcode the input or user Faker gem for input of the method expect the expected result of that method
Upvotes: 1