Intro to RSpec

TDD and BDD

REQUIREMENT

REQUIREMENT

REQUIREMENT

REQUIREMENT

REQUIREMENT

TEST

REQUIREMENT

REQUIREMENT

CODE

Why ?

Is it to attract Ruby job ??

Your first friend to fight Errors

Your guide when refactoring your messed up code

Acts as testable documentation

What is RSpec

DSL for testing Ruby code

Why RSpec?

Widely popular

It doesn't matter which framework you used as long as you write a test

Approach

GREEN

REFACTOR

RED

How To

  1. Choose class / method / behavior to test
  2. Write test
  3. Write code to make the test pass
  4. Refactor code and make sure the test is still passed

Skip this chit-chat

Show me the code!

Assume we have a requirement

As a husband I need to have at least Rp 10.000 in my wallet's balance.

My wife asked me to buy a mango using my balance.

RED

RSpec.describe Wallet do
  subject { Wallet.new(1) }

  it "should have default balance" do
    expect(subject.balance).to eq(10000)
  end
end
RSpec.describe BuyFruit do
  let(:wallet) { Wallet.new(1) }

  it "should have brought fruit" do
    shopping = BuyFruit.call(wallet, 9000)
    
    expect(shopping[:status]).to eq(true)
    expect(shopping[:wallet].balance).to eq(1000)
  end
  
  it "should have not brought fruit" do
    shopping = BuyFruit.call(wallet, 12000)

    expect(shopping[:status]).to be_falsey
    expect(shopping[:wallet].balance).to eq(10000)
  end
end

GREEN

class Wallet
  attr_reader :id, :balance

  def initialize(id, balance = 10000)
    @id = id
    @balance = balance
  end

  def balance=(n)
    @balance = n
  end
end
class BuyFruit
  def self.call(wallet, price)
    options = {}
    options[:wallet] = wallet
    options[:status] = false

    if options[:wallet].balance >= price
      options[:wallet].balance -= price
      options[:status] = true
    end

    options
  end
end

REFACTOR

class DecreaseBalance
  def self.call(wallet, amount)
    options = {}
    options[:wallet] = wallet
    options[:status] = false

    if options[:wallet].balance >= amount
      options[:wallet].balance -= amount
      options[:status] = true
    end

    options
  end
end
class BuyFruit
  def self.call(wallet, price)
    options = {}

    transaction = DecreaseBalance.(wallet, price)
    options[:status] = transaction[:status]
    options[:wallet] = transaction[:wallet]

    options
  end
end

My experiences

  • Don't believe everything what I said
  • Red-Green-Refactor is just a myth for me
  • What I did was Code-Red-Green-Refactor
  • It's okay as long as you write your test
  • But it's better if you write the test first
  • Cover mostly on the business processes

That's all.

Made with Slides.com