我正在使用 GTest 对带有 MFC 类的旧库进行单元测试,并且在 GTest 转换特殊字符时遇到问题。例如,这个测试(故意失败)需要保留项目符号
#include "gtest/gtest.h"
#include <afx.h>
namespace UnitTests
{
TEST(ThisTest, WillFail)
{
CString actual = _T("•");
CString expected = _T("ABC");
EXPECT_STREQ(expected, actual);
}
}
GTest 预期更改为“\xE2\x20AC\xA2”。 Visual Studio 显示了预期字符串的详细信息:
Name Value Type
◢ actual L"•" ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>
GTest 显示失败的测试:
Expected equality of these values:
expected Which is: L"ABC"
actual Which is: L"\xE2\x20AC\xA2"
我无法将 MFC 作为 DLL 包含在 GTest 中,并且 _AFXDLL 被定义为允许 #include
我意识到这个问题可能不是专门针对 GTest 的,而是处理特殊字符时更普遍的问题。
我没有 MFC,但我使用 std::string
检查了你的代码。有两件事可能会有所帮助:
EXPECT_STREQ
,它只能用于 c 字符串(例如 char*
)比较。我建议你改成EXPECT_EQ
。这样做将为您提供如下所示的输出,其格式为 As Text
:expected equality of these values:
expected
Which is: "ABC"
actual
Which is: "\xE2\x80\xA2"
As Text: "•"
这是编码问题。 gtest 认为该字符没有可打印的表示形式,因此它会退回到转义序列中。
在编写处理 Unicode 的测试时遇到类似的问题。
我已经解决了这个问题:
/utf-8
标志即可)。如果您正在使用宽字符进行构建,这应该足以使其工作。我建议像这样配置语言环境(在 gtest init 之前)以在运行时强制执行 UTF-8:
void setupGlobalLocale()
{
const char utf8Name = ".UTF-8";
// C API should use UTF-8
setlocale(LC_CTYPE, utf8Name);
// inform standard library application logic uses UTF-8 - literals are encoded in UTF-8
std::locale::global(std::locale(std::locale("C"), utf8Name, std::locale::ctype));
// use current system encoding for printing
std::locale sysLocale(std::locale(std::locale("C"), "", std::locale::ctype);
std::cout.imbue(sysLocale);
std::cerr.imbue(sysLocale);
std::clog.imbue(sysLocale);
}
int main(int argc, char** argv)
{
setupGlobalLocale();
::testing::InitGoogleMock(&argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
在此 gtest 能够打印正确的字符串之后,许多其他事情开始按预期工作。