我有一个(类成员)函数,我希望避免因模糊而导致应用程序崩溃。为此我添加了一个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 块,但我希望避免使用预处理器宏。
提前致谢,
尼基尔
答案 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);
}