我正在编写单元测试,并尝试涵盖所有代码。
我的代码中有类似的内容:
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();
}
}
我正在阅读这些文档,找不到有关boost::lexical_cast
到std::string
的任何信息。
你能帮我吗?
如果不可能,我将简单地删除此try-catch。如果可能的话,我更喜欢在单元测试中介绍。
我想不出任何理由将词汇铸造到字符串上扔到 bad_lexical_cast
,除了用户定义的类型。如果ValueType
流插入操作员可以在流上设置错误标志,则将导致bad_lexical_cast
。否则,不是。
个人我会保留catch
,即使您只是像int
S这样的内置插入;它不会受到伤害,如果您以某种方式更改lexical_cast
,或者如果您和我都没有考虑过某种边缘情况;如果您不处理由此产生的例外,则在运行时会流产!
如果您担心异常的开销,则可以使用try_lexical_cast
,然后检查其返回true
而不是捕获。但是,如果ValueType
流插入操作员可以投掷,那么您仍然需要能够捕获该异常。
它可能会失败,例如,如果用户定义转换throws:
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
甚至还不够。您的单位测试必须捕获所有例外。
实时演示
唯一的安全和 FutureProof (例如,更新后的更新后没有令人讨厌的惊喜(是用类似的(丑陋(损害您的代码:
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%的代码覆盖范围!