Created
May 23, 2018 12:41
-
-
Save stevo/2d7267e2d015116722ff8750ea7aa473 to your computer and use it in GitHub Desktop.
The BDD story
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1) All right... my task is to sync hotels with Cloudbeds. So probably this will be a rake task, but | |
# for simplicity I will just choose service as my outermost layer! Lets's dive in! I love BDD! | |
module Cloudbeds | |
describe SyncHotels do | |
# 2) it is a service, so to keep convention I'll test .call method | |
# Some small description of what I want it to do won't hurt as well. | |
# Scratch that! Description is essential! | |
describe '.call' do | |
it 'upserts hotels based on data returned from CloudBeds' do | |
# 7) Uh oh! I have realized that we will need to refresh a token once in a while. | |
# I need a place to store this bastard between expiries. Maybe "ApiCredential"? | |
# That is some nice name! Ok... so I'll store access_token here. | |
create(:api_credential, access_token: '123') | |
# 9) Dang! I thought that was it, but after reading description again, I've realized that | |
# I need to handle updating as well... Ok. Let's prepare some existing hotel. | |
existing_hotel = create(:hotel, cloudbeds_hotel_id: 100, name: 'Hilton') | |
# 4) Well... I need to get those hotels from Cloudbeds... | |
# How I would like to get them... hey! It is BDD! Anyhow I like! So maybe some wrapper? | |
# (I could use VCR here... but I would not see correlations between setup and data | |
# created... or maybe webmock... nah - to much knowledge about the structure of responses | |
# for this kind of spec). I will just ask wrapper for hotels and it will return me objects | |
# with everything I need! Sweeeeeet! I know it uses a token that needs to be refreshed | |
# every now and then, so I will go with approach of instantiating client instead of using | |
# static method like CloudbedsWrapper.get_properties. This way I'll be able to keep token | |
# in an instance. I'll assume this wrapper returns me one hotel - London Plaza - sounds PRO! | |
cloudbeds_wrapper = instance_double(CloudbedsWrapper) | |
allow(CloudbedsWrapper).to receive(:new) { cloudbeds_wrapper } | |
allow(cloudbeds_wrapper).to receive(:get_hotels) { | |
[ | |
double(id: 99, name: 'London Plaza'), | |
# 10) Okie dokie. So I will return this extra hotel here for updating purposes. | |
# I need to remember that id should match the one I've created. And then we will | |
# change 'Hilton' to 'Paris'... because it is funny :D | |
double(id: 100, name: 'Paris'), | |
] | |
} | |
expect { | |
# 3) this is how I will call it. Simple! | |
SyncHotels.call | |
# 5) Cool, cool... so this should trigger creation of a hotel! Let's check the count... | |
}.to change { Hotel.count }.by(1) | |
# 6) Damn... count is not precise enough - let's check detailed attributes. I want to | |
# look for the hotel by its cloudbeds_hotel_id and then check if name matches the one | |
# I got from Cloudbeds. Neat! | |
new_hotel = Hotel.find_by(cloudbeds_hotel_id: 99) | |
expect(new_hotel).to have_attributes(name: 'London Plaza') | |
# 11) hahahaha... ok... calm down... now I need to verify, that this update works. Let's just | |
# reload that hotel and see if name is now updated! | |
expect(existing_hotel.reload).to have_attributes(name: 'Paris') | |
# 8) Ok - I have a place to store the token, but I need to make sure that my wrapper uses it! | |
# Let's do it! I'll assume that the token should be passed to constructor. Because why not? | |
expect(CloudbedsWrapper).to have_received(:new).with('123') | |
end | |
end | |
end | |
end | |
# 12) NICE! This spec looks N I C E! I can now dive in into implementation until it turns green. | |
# Probably I will need some more thorough specs for that CloudbedsWrapper because I've stubbed | |
# it (I'll just test what I use - CloudbedsWrapper#get_hotels), but for now I DO NOT HAVE TO CARE :D |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment