I've a function std::vector<Token> tokenize(const std::string& s)
that I want to unit test. The Token
struct is defined as follows:
enum class Token_type { plus, minus, mult, div, number };
struct Token {
Token_type type;
double value;
}
I have set up CppUnitTest and can get toy tests such as 1 + 1 == 2
to run. But when I try to run a test on my tokenize
function it gives me this error:
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> > &).
My testing code is this:
#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);
}
};
}
What's causing the error and how can I fix this?
When you use
Assert::AreEqual
the framework wants to be able to display a string that describes the objects if the assert fails. It uses the templated functionToString
for this, which includes specializations for all the basic data types. For any other data type, you would have to provide a specialization that knows how to format the data into a meaningful string.The simplest solution is to use a different type of assert that doesn't require
ToString
. For example:The other option is to create the
ToString
specialization that the assert needs:I would only go to the trouble of making a specialization if I'm going to be writing a lot of tests using that same object type, and I want to automatically describe the objects.