2009-12-15 3 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 생각할 수 없다.

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 테스트를 작성하는 방법에 어떤 도움을 크게 감상 할 수있다 :

여기 out_of_range의 주요 내 테스트입니다! 감사합니다.

+3

C++의 예외 사양이 다소 손상되었습니다. http://www.gotw.ca/publications/mill22.htm –

+0

MAX_EMPLOYEES를 2로 설정하고 3 번째 직원을 고용하려고하는 것처럼 보입니다.나는 이것이 논리 오류가 아니라 오버플로가되어야한다고 생각한다. –

+0

사실 토마스입니다. 그리고 나는 이것을 위해 논리 오류를 찾기가 어렵다는 것을 알게됩니다. 이 함수에 대한 테스트를 생성해야합니다. 두 유형 모두에서 오류가 발생합니다. 다른 것을 생각할 수 있는지 알려주세요. 고맙습니다. Adri – Adri

답변

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와 비교 한 후 MAX_EMPLOYEES을 돌연변이시키는 것이지만 for 루프 실행을 완료하기 전에 수행해야합니다. 다른 스레드가이 작업을 수행해야하며 적절한 시간에 실행되기를 바랍니다.

둘은 고용 방법을 사용하지 않고 hr.staff 배열을 수정합니다. MAX_EMPLOYEES 급여 객체로 스태프 배열을 채우고 hire 메소드를 호출하면 예외가 발생합니다. 스태프 배열이 비공개라고 가정 할 때 아마 친구 클래스가 이것을 원할 것입니다.

1

이것은 아마도 프로그래밍 실습이 다른 영역 일 것이지만 여기서 예외를 던지기보다는 주장을 제기 할 것입니다.

어설 션은 "절대로 일어나지 않아야 할 일"을 나타 내기 위해 사용됩니다. 프로그래밍 오류로 인해 내부 데이터 손상이 발생하거나 코드가 작성된 가정에 대한 심각한 위반

예외는 일반적으로 예기치 않은 또는 비정상적인 런타임 오류 (디스크 공간 부족, 예기치 않은 네트워크 오류 등)를 나타 내기 위해 사용됩니다.

staffcountstaff이 동기화되지 않은 경우 프로그래밍 오류 및 데이터 손상 가능성이 있음을 나타내며 오류 추적이 양호한 프로그램을 중단하면 손상된 데이터를 계속 사용하는 것이 좋습니다.

C가있는 assert function 내장, 그러나 대안은 (내가 사용) 경량 Boost.Assert로 사용할 수 있으며 Alexandrescu의의와 TORJO의 매우 완전한 기능을 갖춘 SMART_ASSERT library을.

+0

나는 그것이 종속되어 있다고 말할 것이다. 내부 테스트의 경우, 전체 스택이 문제를 이해할 수 있기 때문에 주장이 좋다. 애플리케이션 앞에 클라이언트를 놓을 때 코어 덤프보다 더 나은 것을 원한다. –

+0

+1에 대한 SMART_ASSERT 라이브러리 링크는 알지 못했고 기사는 실제로 계몽 적이기도합니다 (심지어 약간의 매크로 속임수가 있습니다!) –

+0

이것이 Boost.Assert 또는 SMART_ASSERT와 같은 것을 사용하는 이유 중 하나입니다. 어설트 기능; 어설 션 스타일의 로직을 유지할 수 있지만 릴리즈 빌드를위한 코어 덤프보다 사용자 친화적 인 것을 사용하십시오. –

0

여기 정말 질문해야 할 질문이 있습니다. 나는 여러분이 테스트해야 할 것은 예외가 던져지면 시스템의 나머지 부분이 받아 들일 수있게 행동 할 것인가라는 것이다. 이 함수를 일시적으로 예외를 던지는 함수로 임시적으로 대체 할 수 있습니다. 함수를 catch해야하는 함수로 함수가 올바르게 처리되었는지 확인한 다음 올바른 함수를 복원 할 수 있습니다.

관련 문제