为什么GTest要转换特殊字符

问题描述 投票:0回答:2

我正在使用 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 和 CString 的预处理器。

我意识到这个问题可能不是专门针对 GTest 的,而是处理特殊字符时更普遍的问题。

c++ googletest
2个回答
0
投票

我没有 MFC,但我使用 std::string

检查了你的代码
。有两件事可能会有所帮助:

  1. 您正在使用
    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: "•"
  1. 如果您编写自己的类,您可以自定义输出的格式

0
投票

这是编码问题。 gtest 认为该字符没有可打印的表示形式,因此它会退回到转义序列中。

在编写处理 Unicode 的测试时遇到类似的问题。

我已经解决了这个问题:

  • 对所有源文件强制使用 UTF-8 编码
  • 确保编译器在读取源代码并将字符串文字放入最终的精确值时使用 UTF-8(只需在构建中添加
    /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 能够打印正确的字符串之后,许多其他事情开始按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.