The Example in A Field Guide to Unit Testing series in https://jennycodes.me
# frozen_string_literal: true | |
require 'rspec' | |
require_relative 'restaurant' | |
RSpec.describe Restaurant::Server do | |
describe '#take_order' do | |
it 'with French toast passes the order to Cook' do | |
expect_any_instance_of(Restaurant::Cook).to receive(:make_french_toast) | |
Restaurant::Server.new.take_order('French toast') | |
end | |
it 'with other orders returns an error message' do | |
result = Restaurant::Server.new.take_order('Not French toast') | |
expect(result).to be_kind_of String | |
end | |
it 'with other orders does not pass order to Cook' do | |
expect_any_instance_of(Restaurant::Server).not_to receive(:serve) | |
Restaurant::Server.new.take_order('Not French toast') | |
end | |
end | |
describe '#serve' do | |
it 'returns decorated dish as a string' do | |
result = Restaurant::Server.new.serve('French toast is here. Ugh.') | |
expect(result).to eq 'Delicious French toast yo!' | |
end | |
end | |
end | |
RSpec.describe Restaurant::Cook do | |
describe '#make_french_toast' do | |
context 'with ingredients prepared' do | |
it 'returns French toast as string' do | |
allow(Restaurant::StorageRoom).to receive(:get).with('egg').and_return('egg') | |
allow(Restaurant::StorageRoom).to receive(:get).with('bread').and_return('bread') | |
result = Restaurant::Cook.new.make_french_toast | |
expect(result).to eq 'French toast is here. Ugh.' | |
end | |
end | |
context 'without everything prepared' do | |
it 'returns error message - egg' do | |
allow(Restaurant::StorageRoom).to receive(:get).with('egg').and_return(nil) | |
allow(Restaurant::StorageRoom).to receive(:get).with('bread').and_return('bread') | |
result = Restaurant::Cook.new.make_french_toast | |
expect(result).to eq 'Oops running out of eggs!' | |
end | |
it 'returns error message - bread' do | |
allow(Restaurant::StorageRoom).to receive(:get).with('egg').and_return('egg') | |
allow(Restaurant::StorageRoom).to receive(:get).with('bread').and_return(nil) | |
result = Restaurant::Cook.new.make_french_toast | |
expect(result).to eq 'Oops running out of bread!' | |
end | |
end | |
end | |
end |
module Restaurant | |
class Server | |
def take_order(dish) | |
if dish == 'French toast' | |
Cook.new.make_french_toast | |
else | |
"We only make French toast. Take it or leave it." | |
end | |
end | |
# This method is called when Cook is done cooking the dish. | |
def serve(dish) | |
decorated_dish = decorate(dish) | |
"#{decorated_dish} yo!" | |
end | |
private | |
def decorate(dish_with_murmur) | |
dish_name = dish_with_murmur.gsub(' is here. Ugh.', '') | |
"Delicious #{dish_name}" | |
end | |
end | |
class Cook | |
def make_french_toast | |
# [Step 1] Get eggs and bread from StorageRoom | |
egg = StorageRoom.get('egg') | |
bread = StorageRoom.get('bread') | |
# Some error cases handling | |
return 'Oops running out of eggs!' unless egg | |
return 'Oops running out of bread!' unless bread | |
# [Step 2] Making French toast with the eggs and bread | |
puts 'Making French toast' | |
# [Step 3] Return the plate of French toast as a string | |
'French toast is here. Ugh.' | |
end | |
end | |
class StorageRoom | |
def self.get(ingredient) | |
# We don't really care about the implementation. | |
# Just know that it's supposed to return the ingredient if the database has it. | |
end | |
def self.put(ingredient) | |
# We don't really care about the implementation. | |
# Just know that it's supposed to insert the ingredient into the database. | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment