尝试用boost.Test捕获块

try catch blocks with boost.Test

本文关键字:Test boost      更新时间:2023-10-16

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

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块,但我希望避免预处理宏。

提前感谢,

Nikhil

您似乎误解了异常的范围和目的——也许还误解了一般的错误处理。

首先,你应该定义你的函数的先决条件是什么: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);
}