Reputation: 281
I'm implementing a Calculator DSL that has calculate as a method with add, subtract, multiply and divide block within the the method. When I run the rspec test using 'rspec calculator_spec.rb' command, it gives me an undefined method error for 'calculate'. The error is as follows -
1) Calculator Addition operation returns correct values for positive numbers
Failure/Error: calculate do
NoMethodError:
undefined method `calculate' for #<RSpec::ExampleGroups::Calculator::AdditionOperation:0x00000101d14780>
# ./calculator_spec.rb:16:in `block (3 levels) in <top (required)>'
How can I overcome this error?
In calculator.rb -
class Calculator
attr_accessor :total
def calculate(&block)
self.total = 0
instance_eval(&block)
puts total
end
def add(number)
self.total += number
end
def subtract(number)
self.total -= number
end
def multiply(number)
self.total *= number
end
def divide(number)
self.total /= number
end
end
In calculator_spec.rb -
require './calculator'
describe 'Calculator' do
describe "Addition operation" do
it "returns correct values for positive numbers" do
expect(
calculate do
add 2
add 2
end
).to eq(4)
end
it "returns correct values for negative numbers" do
expect(
calculate do
add -2
add -2
end
).to eq(-4)
end
it "returns correct values for positive and negative numbers" do
expect(
calculate do
add 2
add 10
add -10
end
).to eq(2)
end
end
describe "Mixed operations" do
it "returns correct values when mixing all operations" do
expect(
calculate do
add 2
add -2
subtract -2
multiply 10
divide 10
end
).to eq(2)
end
end
end
Upvotes: 0
Views: 1149
Reputation: 37419
Change this line in your rspec:
describe 'Calculator' do
to
describe Calculator do
This will create an implicit subject
of type Calculator
.
Besides that:
calculate
always returns nil
(which is what puts
returns):
def calculate(&block)
self.total = 0
instance_eval(&block)
total # <- no puts
end
You need to call calculate
on your subject
, easiest fix to add a calculate
method on your describe
block:
describe Calculator do
def calculcate(&block)
subject.calculate(&block)
end
describe "Addition operation" do
# ...
Upvotes: 2
Reputation: 118289
I put the code in a file called test.rb file :-
#!/usr/bin/env ruby
class Calculator
attr_accessor :total
def calculate(&block)
self.total = 0
instance_eval(&block)
total
end
def add(number)
self.total += number
end
def subtract(number)
self.total -= number
end
def multiply(number)
self.total *= number
end
def divide(number)
self.total /= number
end
end
Then created the below test_spec.rb file :-
require_relative "../test.rb"
describe 'Calculator' do
describe "Addition operation" do
let(:ob) { Calculator.new }
it "returns correct values for positive numbers" do
expect(
ob.calculate do
add 2
add 2
end
).to eq(4)
end
it "returns correct values for negative numbers" do
expect(
ob.calculate do
add -2
add -2
end
).to eq(-4)
end
it "returns correct values for positive and negative numbers" do
expect(
ob.calculate do
add 2
add 10
add -10
end
).to eq(2)
end
end
describe "Mixed operations" do
let(:ob) { Calculator.new }
it "returns correct values when mixing all operations" do
expect(
ob.calculate do
add 2
add -2
subtract -2
multiply 10
divide 10
end
).to eq(2)
end
end
end
Now run the code as :-
arup@linux-wzza:~/Ruby> rspec -f documentation
Calculator
Addition operation
returns correct values for positive numbers
returns correct values for negative numbers
returns correct values for positive and negative numbers
Mixed operations
returns correct values when mixing all operations
Finished in 0.00197 seconds (files took 0.17971 seconds to load)
4 examples, 0 failures
Your code was not working, as you were calling the method #calculate
on wrong object. You have to call this method, on the Calculator
class instance of-course, as you have defined Calculator#calculate
.
Upvotes: 1