首页 > 解决方案 > 无法使用 Microsoft CppUnitTest 框架在 Visual Studio 2019 上运行测试

问题描述

我有一个std::vector<Token> tokenize(const std::string& s)要进行单元测试的功能。该Token结构定义如下:

enum class Token_type { plus, minus, mult, div, number };

struct Token {
    Token_type type;
    double value;
}

我已经设置了 CppUnitTest 并且可以进行玩具测试,例如1 + 1 == 2运行。但是当我尝试对我的tokenize函数运行测试时,它给了我这个错误:

Error C2338: Test writer must define specialization of ToString<const Q& q> for your class class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __cdecl Microsoft::VisualStudio::CppUnitTestFramework::ToString<class std::vector<struct Token,class std::allocator<struct Token> >>(const class std::vector<struct Token,class std::allocator<struct Token> > &).

我的测试代码是这样的:

#include <vector>

#include "pch.h"
#include "CppUnitTest.h"

#include "../calc-cli/token.hpp"


using namespace std;

using namespace Microsoft::VisualStudio::CppUnitTestFramework;


namespace test_tokens {
    TEST_CLASS(test_tokenize) {
    public:
        TEST_METHOD(binary_operation_plus) {
            auto r = tokenize("1+2");
            vector<Token> s = {
                Token{ Token_type::number, 1.0 },
                Token{ Token_type::plus },
                Token{ Token_type::number, 2.0}
            };

            Assert::AreEqual(r, s);
        }
    };
}

是什么导致了错误,我该如何解决?

标签: c++visual-studiovisual-studio-2019microsoft-cpp-unit-test

解决方案


当您使用Assert::AreEqual框架时希望能够在断言失败时显示一个描述对象的字符串。它为此使用模板化函数ToString,其中包括所有基本数据类型的特化。对于任何其他数据类型,您必须提供知道如何将数据格式化为有意义的字符串的专业化。

最简单的解决方案是使用不需要的不同类型的断言ToString。例如:

Assert::IsTrue(r == s, L"Some descriptive failure message");

另一种选择是创建ToString断言所需的专业化:

#include <CppUnitTestAssert.h>
namespace Microsoft {
    namespace VisualStudio {
        namespace CppUnitTestFramework {
            template<> static inline std::wstring ToString(const std::vector<Token> &t)
            {
                // Write some code here to create a descriptive std::wstring
                return std::wstring("My object description");
            }


        }
    }
}

如果我要使用相同的对象类型编写大量测试,并且我想自动描述这些对象,我只会费心去做专业化。


推荐阅读