如何正确调用Assert::ExpectException?CppUnitTestFramework异常测试报错排查
解决CppUnitTestFramework中ExpectException的C2064编译错误
这个C2064错误的核心原因很明确:你传给Assert::ExpectException的不是一个无参可调用对象,而是直接执行了AutokeyCipher::encrypt(input, primer)的结果。
为什么会报错?
ExpectException的设计逻辑是:它需要接收一个不需要任何参数的函数/可调用体,然后由框架自己去调用这个体,再捕获其中抛出的异常。而你现在的写法是直接调用了encrypt函数,相当于把encrypt的返回值(比如加密后的字符串)传给了ExpectException——这个返回值显然不是一个能接受0个参数的函数,所以编译器就抛出了C2064错误。
正确的写法
最直观也最推荐的方式是用lambda表达式把带参数的函数调用包裹起来,变成无参的可调用对象:
TEST_METHOD(test_for_correct_exception_by_input_with_whitespaces) { std::string input{ "meet me at the corner" }; Assert::ExpectException<std::invalid_argument>([&]() { // 把你的函数调用放在lambda体内 AutokeyCipher::encrypt(input, primer); }); }
这里的[&]表示按引用捕获当前作用域的变量(input和primer),lambda本身是一个无参函数,符合ExpectException的要求。当框架调用这个lambda时,才会执行encrypt函数并触发异常,进而被框架捕获验证。
如果你更倾向于用绑定的方式,也可以用std::bind来把参数绑定成无参函数:
#include <functional> TEST_METHOD(test_for_correct_exception_by_input_with_whitespaces) { std::string input{ "meet me at the corner" }; // 绑定encrypt函数和它的参数,生成无参可调用对象 auto bound_encrypt = std::bind(&AutokeyCipher::encrypt, input, primer); Assert::ExpectException<std::invalid_argument>(bound_encrypt); }
不过这种方式需要注意参数的传递方式(值还是引用),而且可读性不如lambda,所以一般优先推荐lambda写法。
内容的提问来源于stack exchange,提问作者Gino Pensuni
相关产品推荐
相关产品推荐

