所以我其實很羨慕現在幾乎旁邊都有排一個實習生坐在旁邊的設計。
(不過我當初那個樣子我其實也不知道該從哪邊問起好,大概就像一個一般國中數學也2266的人你突然講微積分給他聽,就算他聽不懂也不知道該從哪問好差不多(?))
不過TDD讓我覺得很有親近感,大概因為我是QA出身?,雖然這是兩個不同的概念(p.s QA要做什麼依公司不同可能沒有有些人想的那麼單純,不過這邊省略介紹XD)
http://railsbook.tw/chapters/24-testing-with-rspec-part-2.html
存錢功能 原本帳戶有 10 元,存入 5 元之後,帳戶餘額變 15 元 原本帳戶有 10 元,存入 -5 元之後,帳戶餘額還是 10
元(不能存入小於等於零的金額) 領錢功能 原本帳戶有 10 元,領出 5 元之後,帳戶餘額變 5 元 原本帳戶有 10 元,試圖領出 20
元,帳戶餘額還是 10 元,但無法領出(餘額不足) 原本帳戶有 10 元,領出 -5 元之後,帳戶餘額還是 10
元(不能領出小於或等於零的金額)
RSpec.describe BankAccount do
end
執行會出現下面錯誤,因為還沒有BankAccount這個classNameError:
uninitialized constant BankAccount
硬讓他過的方法
既然他是說找不到BankAccount這個常數,那我給他一個不就好了==+反正他就只是一個會指到BankAccount這個class的常數
但是這樣寫code review的時候大概會被打…
BankAccount = 1
RSpec.describe BankAccount do
end
番外篇
讓class用小寫的方法,雖然實務上用不到..這邊cc就只是一個指向class的變數
同理上面的RSpec.describe BankAccount的BankAccount也是一樣的概念,就一個指到BankAccount class的常數
cc = Class.new do
def hello
puts "hello"
end
end
c = cc.new
c.hello
開始寫吧
上面class也用好之後執行rspec會看到很多像下面那種訊息,說找不到methodNoMethodError:
undefined method `deposit' for #<BankAccount:0x007f9b0b6121c0 @amount=10>
要解決很簡單~給他一個就好了~就算裡面是空的也可以def deposit(amount)
end
把該加的method都給他之後,現在錯誤訊息應該會像下面這樣 expected #<Fixnum:31> => 15
got #<Fixnum:21> => 10
原因也很簡單,因為現在method都是空的,裡面沒有做任何的運算,當然數字不會變成15,正確應該要改成這樣class BankAccount
def initialize(amount)
@amount = amount
end
def deposit(amount)
@amount += amount
end
def balance
@amount
end
end
這樣子”原本帳戶有 10 元,存入 5 元之後,帳戶餘額變 15 元“就會pass了 可是存款不可能存負得值進去,所以要加一下判斷
def deposit(amount)
@amount += amount if amount > 0
end
這樣子“存錢功能”兩個就都會pass了。 領錢和提錢的概念差不多,下面是完整的樣子
class BankAccount
def initialize(amount)
@amount = amount
end
def deposit(amount)
@amount += amount if amount > 0
end
def balance
@amount
end
def withdraw(amount)
# ">0"可以用positive?代替,可是這樣多打好多字
if amount > 0 && enough?(amount)
@amount -= amount
end
end
private
def enough?(amount)
balance >= amount
end
end
RSpec.describe BankAccount do
describe "存錢功能" do
it "原本帳戶有 10 元,存入 5 元之後,帳戶餘額變 15 元" do
account = BankAccount.new(10)
account.deposit 5
expect(account.balance).to be 15
end
it "原本帳戶有 10 元,存入 -5 元之後,帳戶餘額還是 10 元(不能存入小於等於零的金額)" do
account = BankAccount.new(10)
account.deposit -5
expect(account.balance).to be 10
end
end
describe "領錢功能" do
it "原本帳戶有 10 元,領出 5 元之後,帳戶餘額變 5 元" do
account = BankAccount.new(10)
account.withdraw 5
expect(account.balance).to be 5
end
it "原本帳戶有 10 元,試圖領出 20 元,帳戶餘額還是 10 元,但無法領出(餘額不足)" do
account = BankAccount.new(10)
account.withdraw 20
expect(account.balance).to be 10
end
it "原本帳戶有 10 元,領出 -5 元之後,帳戶餘額還是 10 元(不能領出小於或等於零的金額)" do
account = BankAccount.new(10)
account.withdraw -5
expect(account.balance).to be 10
end
end
end
哎~可是好像很多一樣的code出現了好幾次,看起來好討厭
let
可以用let解決這個問題let(:account) { BankAccount.new(10) }
雖然看起來像是變數,實際上他是幫你定義一個account方法所以如果你把測項裡的account改成account(),他還是會動,所以他真的是個method,只是在ruby裡面小括號是可以被省略的。 it "原本帳戶有 10 元,存入 -5 元之後,帳戶餘額還是 10 元(不能存入小於等於零的金額)" do
account().deposit -5
expect(account.balance).to be 10
end
before
也可以用before來解決這個問題,但是因為必須要用實體變數下面的測項才有辦法用,所以要記得除了把本來每個測試裡面的account = BankAccount.new(10)刪掉以外,也要記得把account改成@account before :each do
@account = BankAccount.new(10) #要用實體變數
end
all
另外除了before也有all可以用,但all只會在最一開始被執行一次完整版
class BankAccount
def initialize(amount)
@amount = amount
end
def deposit(amount)
@amount += amount if amount > 0
end
def balance
@amount
end
def withdraw(amount)
# ">0"可以用positive?代替
if amount > 0 && enough?(amount)
@amount -= amount
end
end
private
def enough?(amount)
balance >= amount
end
end
RSpec.describe BankAccount do
let(:account) { BankAccount.new(10) }
# def account
# @tmp ||= BankAccount.new(10)
# end
# #all只會跑一次
# before :all do
# puts "hi @ all"
# end
describe "存錢功能" do
it "原本帳戶有 10 元,存入 5 元之後,帳戶餘額變 15 元" do
account.deposit 5
expect(account.balance).to be 15
end
it "原本帳戶有 10 元,存入 -5 元之後,帳戶餘額還是 10 元(不能存入小於等於零的金額)" do
account.deposit -5
expect(account.balance).to be 10
end
end
describe "領錢功能" do
it "原本帳戶有 10 元,領出 5 元之後,帳戶餘額變 5 元" do
account.withdraw 5
expect(account.balance).to be 5
end
it "原本帳戶有 10 元,試圖領出 20 元,帳戶餘額還是 10 元,但無法領出(餘額不足)" do
account.withdraw 20
expect(account.balance).to be 10
end
it "原本帳戶有 10 元,領出 -5 元之後,帳戶餘額還是 10 元(不能領出小於或等於零的金額)" do
account.withdraw -5
expect(account.balance).to be 10
end
end
end
Written with StackEdit.
沒有留言:
張貼留言