C ++, как проверить функцию, чтобы она выдавала ошибку? - PullRequest
0 голосов
/ 15 декабря 2009

Функция, которая должна быть протестирована:

 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

Ответы [ 4 ]

1 голос
/ 15 декабря 2009

Вероятно, это область, в которой методы программирования различаются, но я бы поднял утверждение, а не выбросил бы здесь исключение.

Утверждения используются для обозначения «того, что никогда не должно происходить»; ошибка программирования, которая может привести к повреждению внутренних данных или серьезному нарушению допущений, в соответствии с которыми был написан код.

Исключения обычно используются для указания неожиданных или необычных ошибок времени выполнения (нехватка места на диске, непредвиденные сетевые ошибки и т. Д.).

Если staffcount и staff не синхронизированы, это указывает на ошибку программирования и вероятное повреждение данных, и прерывание программы (с хорошим отслеживанием ошибок) может быть предпочтительнее продолжения с поврежденными данными.

C имеет встроенную функцию assert , но доступны альтернативы, такие как облегченный Boost.Assert (который я использую) и очень полный Александреску и Торхо библиотека SMART_ASSERT .

1 голос
/ 15 декабря 2009

Вам не нужна оптимизация в начале. Если вы пропустите это, то у вас будет только одно исключение, которое вам нужно сгенерировать, вы не сможете делать логические ошибки и у вас не будет проблем с его тестированием. Медленнее, да, но если вы все равно выбрасываете исключение, я сомневаюсь, что это что-то меняет. Это также дает более простую функцию. Вот код:

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 голосов
/ 15 декабря 2009

Вопрос в том, что вам действительно нужно проверить. Я бы сказал, что вам нужно проверить, будет ли остальная часть вашей системы вести себя приемлемо после выдачи исключения. Учитывая это, вы можете временно заменить эту функцию на функцию, которая просто генерирует исключение, убедитесь, что она обрабатывается правильно всем, что должно ее перехватить, и восстановите правильную функцию.

0 голосов
/ 15 декабря 2009

Есть два способа обойти это исключение.

Можно было бы мутировать MAX_EMPLOYEES после сравнения с staff_count, но до того, как вы закончили выполнение цикла for. Вам нужно, чтобы другой поток делал это, и надеюсь, что он будет запущен в нужное время.

Два будут модифицировать массив hr.staff без использования метода найма. Если вы заполните массив персонала объектами MAX_EMPLOYEES Payroll, а затем вызовете метод найма, вы получите это исключение. Возможно, вы захотите, чтобы класс друзей сделал это, так как я предполагаю, что массив персонала является личным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...