2015-05-11 39 views
0

我有一個C++類,以下列方式生成唯一的ID。需要幫助谷歌測試一個唯一的Id生成器

class Foo 
{ 
    static int seed; 
public: 
    const int Uid; 
    Foo() : Uid(seed++) {} 
} 

int Foo::seed = 0; 

現在我使用的是谷歌測試使用,以測試這個ID生成器:

Foo foo; 
EXPECT_EQ(0, foo.Uid); 
Foo foo2; 
EXPECT_EQ(1, foo2.Uid); 

這個測試傳球,當我調試它但是當我真正運行失敗,給我的的ID 2和3代替。有人可以幫我弄清楚爲什麼? Google測試是否會連續進行其中兩項測試?

回答

5

良好測試的特點之一是不依賴於測試訂單執行的可重複性。

你有一個單身人士,你用它壞的方式。如果我們假設沒有內存問題,那麼最可能發生的情況是Foo類型的對象在某處創建,並且您的測試以不同的順序執行以進行調試和正常運行。這將解釋不同的結果。

如何解決?最簡單的方法是添加一個方法來重置計數器,並在setUp()中調用它。要正確地修復它,你需要考慮如何移除這個單例。

+0

非常多 - 這就是爲什麼全局可變狀態不好。 – Puppy

3

BЈовић's answer會讓你在那裏。您的測試代碼中的其他位置很可能會創建Foo的另一個實例,以增加靜態成員的值。

這可能是少哈克的解決方案和可能有用的,如果增加一個公共的復位方法不適用(即你不想測試代碼添加到您的API):

  1. 模擬類。添加一個來自Foo的dervies類。將您的靜態變量的訪問級別從private更改爲protected,並將新的reset方法添加到受保護的類。然後,您可以重構測試代碼以運行派生類。
  2. 讓FooTester成爲Foo的朋友。通過班級朋友船,您可以讓您的測試代碼更多地在被測試的班上操作。

我建議去模擬路線。保持原始類清除任何特定的測試攻擊,並允許您更好地瞭解其界面中的任何暴露。

+0

對於模擬類,他需要使用依賴注入和重新設計。但好建議。 –