我有一个(类成员)函数,我希望避免应用程序因歧义而崩溃。为此,我添加了一个 try catch block ,如下所示:
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 block 在发布设置中运行良好。但是,只有当我删除 try-catch block 并让函数抛出异常时,这个测试才有效。
什么是让这两个东西正常工作的最佳方法,以便在运行中提示用户正确的错误,同时测试明确检查调试?一种方法是使用#ifdef/#endif DEBUG block ,但我希望避免预处理器宏。
提前致谢
尼基尔
最佳答案
您似乎误解了异常的范围和目的 - 并且可能误解了一般的错误处理。
首先,您应该定义函数的前提条件是什么:getGene()
是否总是期望 position
是有效的?它是否希望其客户永远提供无效头寸?
如果是这种情况,则提供无效位置的客户端(即使客户端是测试例程)正在破坏与 getGene()
的契约(特别是,它正在破坏其前提条件),并且根据定义,违反契约(Contract)是未定义的行为。 你不能测试未定义的行为,所以你应该删除你的测试。
另一方面,如果您的函数具有广泛的契约,即它允许客户端传入任何位置(即使是无效位置)并且 (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);
}
关于c++ - 尝试使用 boost.Test 捕获 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17152084/