Rspec testing
I have class called Client.
class Client
class << self
def shutdown
puts 'shutting down the producer gracefully'
@producer ||= k_producer.producer(opts)
@producer.shutdown
end
private
def k_producer
Kafka.new([127.0.0.1:9092], { required_acks: :all })
end
end
end
I want to test the shutdown class method and i do not understand the concept of stubbing or spy.
Im trying this way
RSpec.describe Client do
describe "Client.shutdown" do
it "calls shutdown" do
described_class.shutdown
expect(described_class).to have_received(:shutdown)
end
end
end
I'm getting this error where i do not know how to tell the rspec that i have @producer inside my class and shutdown is called on it.
Client (class)> expected to have received shutdown, but that object is not a spy or method has not been stubbed
You never set up described_class
as a spy. You'd do this by making it a partial double with allow
.
RSpec.describe Client do
describe "Client.shutdown" do
it "calls shutdown" do
allow(described_class).to receive(:shutdown)
described_class.shutdown
expect(described_class).to have_received(:shutdown)
end
end
end
However, this test is tautological. You're simply testing that the test called Client.shutdown
. It's more useful to test that @producer.shutdown
is called.
It's a bit troublesome to get at @producer. We can make Client easier to test, and more flexible in general, by adding accessors for its internal objects.
class Client
class << self
# Define only the writers: producer= and kafka=
attr_writer :producer, :kafka
# Define the readers ourselves with our defaults.
def producer
@producer ||= kafka.producer(opts)
end
def kafka
@kafka ||= Kafka.new(["127.0.0.1:9092"], { required_acks: :all })
end
def shutdown
puts 'shutting down the producer gracefully'
producer.shutdown
end
end
end
Now we make a spy and set it as the producer.
RSpec.describe Client do
describe "Client.shutdown" do
it "calls @producer.shutdown" do
producer = spy("producer")
described_class.producer = producer
described_class.shutdown
expect(producer).to have_received(:shutdown)
end
end
end