該文章同步發佈於:我的部落格
也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!
昨天我們的測試竟然沒有通過...
到底發生了什麼?該怎麼讓它通過?那串紅紅的字看起來就很不順眼,我們該怎麼做呢?放心!今天就會讓你感受的綠燈的療癒~
我們來看看他說我們錯誤的地方在哪,首先是這串:
Failure/Error: burger = Burger.new('Big mac')
但好像沒有告訴我們錯在哪裡耶?喔喔!我們再往下看
NameError:
uninitialized constant Burger
他的意思是我們並沒有初始化一個常數 Burger
這就是 Ruby 或是 寫 Rails 時超級常見的錯誤,請筆記!
我們需要擁有一個類別,然後呼叫 initialize
這個方法,這樣我們才可以生出 burger
這個物件!
我們要寫在哪裡呢?其實可以直接寫在測試的上面,但這並不是一個好方法,我們在寫測試的時候會希望把每隻檔案分開的放置,這樣才是看起來專業的方法!
現在這是我們的檔案結構,這樣也很明顯地可以理解到,burger_spec.rb
就是拿來測試 burger.rb
這支檔案的!
接著我們在 burger.rb
中寫入:
class Burger
end
再輸入一次 rspec spec/burger_spec.rb
,看看錯誤的訊息是什麼?
雖然還是錯誤的還是同一行,但錯誤的內容已經不一樣了,我們繼續來解決這個問題,他說我的給予的參數是錯誤的,代表說我們需要在類別初始化的時候加入參數,來讓這個錯誤訊息通過,實作吧!
class Burger
def initialize(type)
@type = type
end
end
好的,我們一樣在執行一次 rspec spec/burger_spec.rb
通常看到錯誤訊息有所改變的時候,都會覺得鬆一口氣的感覺,至少事情產生變化了~
因為我們又更近了一步了!代表每一次的改動都有正中紅心,也有根據錯誤訊息來做正確的改動!
這次的錯誤也是很常見的 NoMethodError
意指我們沒有 type
這個方法,如果是別的語言來的人可能會覺得很奇怪,取得屬性還要什麼方法?
事實上在 Ruby 的世界裡都是物件,而取值也會是物件的其中一個方法,包括設置值也是喔!
class Burger
def initialize(type)
@type = type
end
def type # 這個是取值的方法
@type
end
def type=(type) # 這個是賦值的方法
@type = type
end
end
來看看我們把取值的方法加上去之後會發生什麼事情吧?
登愣登愣!!成功啦!我們通過這次的測試了!
但別高興得太早,還記得 TDD 測試中通過綠色後要進行的環節嗎?
沒錯,就是重構的部分,這也是非常重要的!
我們這時候回頭看一下我們“測試碼”以及“真實程式碼”有沒有什麼需要改進的地方。
測試的部分因為只有兩行,好像沒什麼可以縮減的部分了,我們就看看“真實程式碼”吧!
關於取值、賦值兩個方法,Ruby 其實有提供我們更便捷的方式來用,不需要這樣子寫到六行,讓我們來重構看看這段程式碼吧!
class Burger
attr_accessor :type
def initialize(type)
@type = type
end
end
這個的效果,和我們原先寫的方式是一樣的喔!但礙於這個主要是在介紹 RSpec,關於 Ruby 的基礎我們就不提到太多!主要還是以通過測試的邏輯為主。
從第一天到現在也說了蠻多的東西了,有一些小測驗希望可以讓剛學的人回想一下,自己想的是錯誤還是正確!
example
?example group
?assertion
? ( 類似主張、斷言的感覺)expect.eq(1 + 1, 2)
這是正確的寫法嗎?如果是錯的,為什麼?example
,只要打開一個 _spec.rb
的檔案直接寫就可以了嗎?describe
語法一定要有參數才可以運作嗎?E2E Test, Integration Test, Unit Test
)這些答案在之前的文章都有提過喔!
明天會在一個添加許多的 example
在一個測試之中,順便也訓練我們思考 TDD 的思緒,然後繼續的面對錯誤,修正,重構,這樣自然而然就會越來越有感覺~