Skip to content

Instantly share code, notes, and snippets.

@wojtekmach
Created May 3, 2012 09:45
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wojtekmach/2584768 to your computer and use it in GitHub Desktop.
Save wojtekmach/2584768 to your computer and use it in GitHub Desktop.
Writing MiniTest extensions
require 'minitest/autorun'
module MiniTest::Assertions
def assert_changes(obj, method, exp_diff)
before = obj.send method
yield
after = obj.send method
diff = after - before
assert_equal exp_diff, diff, "Expected #{obj.class.name}##{method} to change by #{exp_diff}, changed by #{diff}"
end
end
module MiniTest::Expectations
infect_an_assertion :assert_changes, :must_change
end
class Account
attr_reader :balance
def initialize(balance = 0)
@balance = balance
end
def credit(amount)
check_amount amount
@balance += amount
end
def debit(amount)
check_amount amount
raise RuntimeError, "Unsufficient funds" if amount > balance
@balance -= amount
end
private
def check_amount(amount)
raise ArgumentError, "Amount must be > 0" unless amount > 0
end
end
describe Account do
before { @account = Account.new 100 }
describe '#credit' do
it "fails when amount <= 0" do
lambda { @account.credit 0 }.must_raise ArgumentError
end
it "increases balance" do
lambda { @account.credit 50 }.must_change @account, :balance, +50.0
end
end
describe '#debit' do
it "fails when amount <= 0" do
lambda { @account.debit 0 }.must_raise ArgumentError
end
it "fails when amount is greater than balance" do
lambda { @account.debit 500 }.must_raise RuntimeError
end
it "decreases balance" do
lambda { @account.debit 50 }.must_change @account, :balance, -50.0
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment