- RSpec 教程
- RSpec - 首頁
- RSpec - 簡介
- RSpec - 基本語法
- RSpec - 編寫規範
- RSpec - 匹配器
- RSpec - 測試替身
- RSpec - 存根
- RSpec - 鉤子
- RSpec - 標籤
- RSpec - 主題
- RSpec - 輔助函式
- RSpec - 元資料
- RSpec - 過濾
- RSpec - 期望
- RSpec 資源
- RSpec - 快速指南
- RSpec - 有用資源
- RSpec - 討論
RSpec - 測試替身
本章我們將討論 RSpec Doubles,也稱為 RSpec 模擬物件。Double 是一個可以“代替”另一個物件的 object。您可能想知道這究竟意味著什麼以及為什麼需要它。
假設您正在為學校構建一個應用程式,並且您有一個表示學生教室的類和另一個表示學生的類,也就是說,您有一個 Classroom 類和一個 Student 類。您需要先編寫其中一個類的程式碼,所以假設從 Classroom 類開始:
class ClassRoom
def initialize(students)
@students = students
end
def list_student_names
@students.map(&:name).join(',')
end
end
這是一個簡單的類,它有一個方法 list_student_names,該方法返回一個用逗號分隔的學生姓名字串。現在,我們想要為這個類建立測試,但是如果我們還沒有建立 Student 類,我們該怎麼做呢?我們需要一個測試替身。
此外,如果我們有一個像 Student 物件一樣工作的“虛擬”類,那麼我們的 ClassRoom 測試將不會依賴於 Student 類。我們稱之為測試隔離。
如果我們的 ClassRoom 測試不依賴於任何其他類,那麼當測試失敗時,我們可以立即知道我們的 ClassRoom 類中存在錯誤,而不是其他某個類中存在錯誤。請記住,在現實世界中,您可能正在構建一個需要與其他人編寫的另一個類互動的類。
這就是 RSpec Doubles(模擬物件)變得有用的地方。我們的 list_student_names 方法在其 @students 成員變數中的每個 Student 物件上呼叫 name 方法。因此,我們需要一個實現了 name 方法的 Double。
以下是 ClassRoom 的程式碼以及一個 RSpec 示例(測試),但請注意,沒有定義 Student 類:
class ClassRoom
def initialize(students)
@students = students
end
def list_student_names
@students.map(&:name).join(',')
end
end
describe ClassRoom do
it 'the list_student_names method should work correctly' do
student1 = double('student')
student2 = double('student')
allow(student1).to receive(:name) { 'John Smith'}
allow(student2).to receive(:name) { 'Jill Smith'}
cr = ClassRoom.new [student1,student2]
expect(cr.list_student_names).to eq('John Smith,Jill Smith')
end
end
執行上述程式碼時,將產生以下輸出。您計算機上的經過時間可能略有不同:
. Finished in 0.01 seconds (files took 0.11201 seconds to load) 1 example, 0 failures
如您所見,使用**測試替身**允許您即使在程式碼依賴於未定義或不可用的類時也能測試程式碼。此外,這意味著當測試失敗時,您可以立即知道這是由於您自己的類中的問題造成的,而不是其他人編寫的類。