boost::lexical_cast 到 std::string 什么时候失败?
When does boost::lexical_cast to std::string fail?
我正在编写单元测试并试图覆盖我的所有代码。
我的代码中有这样的东西:
template<typename ValueType>
std::string ConvertToStringUsingBoost(ValueType const& v)
{
try
{
return boost::lexical_cast<std::string, ValueType>(v);
}
catch(boost::bad_lexical_cast const& e)
{
LOG_ERR("Fail to cast %s to string", e.source_type().name);
return std::string();
}
}
我正在阅读 these docs,但找不到有关 boost::lexical_cast
到 std::string
何时可以抛出异常的任何信息。
你能帮我吗?
如果不可能,我将删除此 try-catch。如果可能的话,我更愿意在单元测试中涵盖这一点。
除了用户定义的类型,我想不出有任何理由将词法转换为字符串抛出 bad_lexical_cast
。如果 ValueType
流插入运算符可以在流上设置错误标志,那么这将导致 bad_lexical_cast
。否则不行。
我个人会保留 catch
,即使您只是转换像 int
s 这样的内置函数;如果您以某种方式更改 lexical_cast
,或者如果有一些您和我都没有考虑过的边缘情况,它不会造成伤害,并且可能会发现错误;如果您不处理由此产生的异常,您将在运行时中止!
如果您担心异常的开销,可以改用 try_lexical_cast
并检查它 returns true
而不是捕获。但是,如果 ValueType
流插入运算符可以抛出异常,那么您仍然需要能够捕获该异常。
唯一安全且 未来无虞(例如,boost 更新后没有令人讨厌的惊喜)是用这样的(丑陋的)东西来破坏你的代码:
template<typename ValueType>
std::string ConvertToStringUsingBoost(ValueType const& v)
{
try
{
#ifdef UNITTEST
if (unittest == case_fail) {
throw boost::bad_lexical_cast();
}
#endif
return boost::lexical_cast<std::string, ValueType>(v);
}
catch(boost::bad_lexical_cast const& e)
{
LOG_ERR("Fail to cast %s to string", e.source_type().name);
return std::string();
}
}
现在您应该能够达到 ~100% 的代码覆盖率!
它可能会失败,例如,如果 用户定义的 转换抛出:
enum class MyType {};
std::ostream& operator<<( std::ostream&, MyType const& )
{
throw "error";
}
int main()
{
try
{
boost::lexical_cast< std::string >( MyType{} );
}
catch(...)
{
std::cout << "lexical_cast exception";
}
}
由于您无法控制用户定义的转换抛出的异常类型,因此捕获 boost::bad_lexical_cast
甚至是不够的。您的单元测试必须捕获所有异常。
我正在编写单元测试并试图覆盖我的所有代码。
我的代码中有这样的东西:
template<typename ValueType>
std::string ConvertToStringUsingBoost(ValueType const& v)
{
try
{
return boost::lexical_cast<std::string, ValueType>(v);
}
catch(boost::bad_lexical_cast const& e)
{
LOG_ERR("Fail to cast %s to string", e.source_type().name);
return std::string();
}
}
我正在阅读 these docs,但找不到有关 boost::lexical_cast
到 std::string
何时可以抛出异常的任何信息。
你能帮我吗?
如果不可能,我将删除此 try-catch。如果可能的话,我更愿意在单元测试中涵盖这一点。
除了用户定义的类型,我想不出有任何理由将词法转换为字符串抛出 bad_lexical_cast
。如果 ValueType
流插入运算符可以在流上设置错误标志,那么这将导致 bad_lexical_cast
。否则不行。
我个人会保留 catch
,即使您只是转换像 int
s 这样的内置函数;如果您以某种方式更改 lexical_cast
,或者如果有一些您和我都没有考虑过的边缘情况,它不会造成伤害,并且可能会发现错误;如果您不处理由此产生的异常,您将在运行时中止!
如果您担心异常的开销,可以改用 try_lexical_cast
并检查它 returns true
而不是捕获。但是,如果 ValueType
流插入运算符可以抛出异常,那么您仍然需要能够捕获该异常。
唯一安全且 未来无虞(例如,boost 更新后没有令人讨厌的惊喜)是用这样的(丑陋的)东西来破坏你的代码:
template<typename ValueType>
std::string ConvertToStringUsingBoost(ValueType const& v)
{
try
{
#ifdef UNITTEST
if (unittest == case_fail) {
throw boost::bad_lexical_cast();
}
#endif
return boost::lexical_cast<std::string, ValueType>(v);
}
catch(boost::bad_lexical_cast const& e)
{
LOG_ERR("Fail to cast %s to string", e.source_type().name);
return std::string();
}
}
现在您应该能够达到 ~100% 的代码覆盖率!
它可能会失败,例如,如果 用户定义的 转换抛出:
enum class MyType {};
std::ostream& operator<<( std::ostream&, MyType const& )
{
throw "error";
}
int main()
{
try
{
boost::lexical_cast< std::string >( MyType{} );
}
catch(...)
{
std::cout << "lexical_cast exception";
}
}
由于您无法控制用户定义的转换抛出的异常类型,因此捕获 boost::bad_lexical_cast
甚至是不够的。您的单元测试必须捕获所有异常。