尝试使用boost.Test捕获块

时间:2013-06-17 16:11:00

标签: c++ try-catch boost-test

我有一个(类成员)函数,我希望避免因模糊而导致应用程序崩溃。为此我添加了一个try catch bock,如下所示:

void getGene(unsigned int position){
     T val;
     try {
        val =  _genome.at(_isCircular ? position % _genome.size() : position);
     }
     catch (std::exception& e) {
         std::cerr << "Error in [" << __PRETTY_FUNCTION__ << "]: " 
                   << e.what()  << std::endl;
         exit(1);
    }
    return val;
}

现在,我希望添加一个Boost单元测试,我想这样做

BOOST_AUTO_TEST_CASE(nonCircularGenome_test){

   // set size to 10
   test.setSize(10);
   // set non circular
   test.setNonCircular();    

   // gene at site # 12 does not exist in a 10-site long genome, must throw an exception
   BOOST_CHECK_THROW(test.getGene(12), std::out_of_range);

问题是,我无法让这两件事都奏效。 try-catch块在发布设置中运行良好。但是,只有当我删除try-catch块并让函数抛出异常时,此测试才有效。

让这两件事都运行的最佳方法是什么,以便在运行时提示用户输入正确的错误,同时测试会明确检查调试?一种方法是使用#ifdef / #endif DEBUG 块,但我希望避免使用预处理器宏。

提前致谢,

尼基尔

1 个答案:

答案 0 :(得分:3)

您似乎误解了异常的范围和目的 - 或许可能是错误处理。

首先,您应该定义您的函数的前提条件:getGene()始终期望position是有效的吗?是否期望其客户从不提供无效职位?

如果是这种情况,提供无效职位的客户(即使客户是测试例程)正在违反与getGene()的合同(特别是,它正在打破其先决条件),根据定义,破坏合同是未定义的行为。 您无法测试未定义的行为,因此您应该删除测试。

另一方面,如果你的函数有一个广泛的契约,即它允许客户传入任何位置(甚至是无效的)和(a)抛出异常或(b)返回当位置无效时传递失败的错误代码,则exit(1)行不应该存在,因为您正在退出程序并且控制权不会传回给调用者。

一种可能性是在记录诊断后重新抛出异常:

T getGene(unsigned int position){
    T val;
    try {
       val =  _genome.at(_isCircular ? position % _genome.size() : position);
    }
    catch (std::exception& e) {
        std::cerr << "Error in [" << __PRETTY_FUNCTION__ << "]: " 
                  << e.what()  << std::endl;

        throw;
//      ^^^^^
    }
    return val;
}

如果您不需要打印诊断程序,只需让异常自然传播:

T getGene(unsigned int position){
    return _genome.at(_isCircular ? position % _genome.size() : position);
}