2009-12-15 71 views
0

需要被測試的功能是:C++如何測試函數使其拋出一個錯誤?

int hire(Payroll * p) throw(out_of_range, logic_error) 
{ 

     // error if no holes left 

     if (staffcount == MAX_EMPLOYEES) 
        throw (out_of_range("Hire: Too many employees")); 

     // spin down holes looking for a hole. 
     for (int i = 0; i < MAX_EMPLOYEES; ++i) { 
      Payroll *current = staff[i].get(); // get the pointer 

      if (current == 0) { // it is empty 
       appay newpay(p); // convert *Payrollto auto_ptr 
       staff[i] =newpay; 
       staffcount++; // one more staff 
       return i;  // return index 
      } else { 
       // do nothing. Hole is filled 
      } 
     } 
     // should never get here 
     throw (logic_error("no holes, but count ok")); } 

我可以拋出一個out_of_range錯誤來測試它,但我想不出任何logic_error的。

這是我的主要測試out_of_range

try { 
    for (int i = 0; i<11; i++){ 
     hr.hire(new Payroll("Prog M. Er", 55757575)); 
     hr.showAllStaff(" after hires"); 
    } 
} catch (out_of_range e) { 
    cout << "Out of range error: " << e.what() << endl; 
    cout << "DEBUG: carry on processing - line 177 was tested\n"; 
} 

如何編寫此功能的測試logic_error任何幫助將不勝感激! 謝謝。

A

+3

C++中的異常規範有些破碎:http://www.gotw.ca/publications/mill22.htm – 2009-12-15 17:51:50

+0

看起來像是您將MAX_EMPLOYEES設置爲2並嘗試僱用第三名員工。我不認爲這應該是一個邏輯錯誤,但更多的是溢出。 – 2009-12-15 18:08:25

+0

這是真的托馬斯。我發現很難找到這個邏輯錯誤。我需要爲這個函數創建一個測試,在這裏我拋出錯誤(兩種類型)。 讓我知道如果你能想到別的。謝謝。 Adri – Adri 2009-12-15 18:52:53

回答

1

您在開始時並不需要進行優化。如果你忽略了這一點,那麼你只需要拋出一個異常,那麼你就不會犯邏輯錯誤,而且你也沒有任何問題對它進行測試。更慢,是的,但如果你拋出異常,我懷疑它有什麼不同。它也提供了一個更簡單的功能。這裏是代碼:

int hire(Payroll * p) throw (out_of_range) 
{ 
    // spin down holes looking for a hole. 
    for (int i = 0; i < MAX_EMPLOYEES; ++i) 
    { 
     Payroll *current = staff[i].get(); // get the pointer 

     if (current == 0) { // it is empty 
      appay newpay(p); // convert *Payrollto auto_ptr 
      staff[i] =newpay; 
      staffcount++; // one more staff 
      return i;  // return index 
     } else { 
      // do nothing. Hole is filled 
     } 
    } 

    // error if no holes left 
    throw (out_of_range("Hire: Too many employees")); 
} 
0

有兩種方法我可以想到擊中該異常。

與staff_count進行比較後,在完成執行for循環之前,可能會對MAX_EMPLOYEES進行變異。你必須有另一個線程做到這一點,並希望它在正確的時間運行。

兩個會修改hr.staff數組而不使用hire方法。如果使用MAX_EMPLOYEES Payroll對象填充員工數組,然後調用hire方法,那麼您會遇到該異常。你可能會想要一個朋友類來做到這一點,因爲我認爲這個員工數組是私人的。

1

這可能是一個編程實踐不同的領域,但我會提出一個斷言,而不是在這裏拋出異常。

斷言用於表示「永遠不應該發生」;編程錯誤,可能導致內部數據損壞,或嚴重違反編寫代碼的假設。

異常通常用於指示意外的或異常的運行時錯誤(超出磁盤空間,意外的網絡錯誤等)。

如果staffcountstaff不同步,表明編程錯誤和可能的數據損壞,並且中止程序(具有良好的錯誤跟蹤)可能更適合繼續損壞的數據。

C有一個內置的assert function,但有替代品可供選擇,如輕量級Boost.Assert(我使用)和Alexandrescu和Torjo的非常全功能的SMART_ASSERT library

+0

我會說這取決於:對於內部測試來說,斷言是很好的,因爲你得到整個堆棧來理解問題。當你把一個客戶端放在你的應用程序前面時,你絕對需要比核心轉儲更好的東西! – 2009-12-15 19:09:46

+0

+1爲SMART_ASSERT庫鏈接,不知道它和文章是真正啓發(甚至有一點宏觀欺騙!) – 2009-12-15 19:48:34

+0

這是使用像Boost.Assert或SMART_ASSERT,而不是內置斷言功能;您可以保留斷言樣式的邏輯,但使用比核心轉儲更方便用戶的內容來發布版本。 – 2009-12-15 20:12:41

0

這裏的問題是你真正需要測試的。我會說,你需要測試的是一旦拋出異常,系統的其他部分是否可以接受。鑑於此,您可能會暫時將此函數替換爲僅引發異常的函數,並確保它被正確處理,然後恢復正確的函數。