如何使用 GTest 测试具有多个模板参数的 C++ 模板 class?
How to test C++ template class with multiple template parameters with GTest?
我有一个小class:
template <class key_t, class value_t>
class node_t {
public:
node_t();
void set_key(key_t);
key_t get_key();
void set_value(value_t);
value_t get_value();
private:
key_t key;
value_t value;
};
template <class key_t, class value_t>
node_t<key_t, value_t>::node_t() {
key = (key_t)0;
value = (value_t)0;
}
template <class key_t, class value_t>
void node_t<key_t, value_t>::set_key(key_t key) {
this->key = key;
}
template <class key_t, class value_t>
key_t node_t<key_t, value_t>::get_key() {
return this->key;
}
template <class key_t, class value_t>
void node_t<key_t, value_t>::set_value(value_t value) {
this->value = value;
}
template <class key_t, class value_t>
value_t node_t<key_t, value_t>::get_value() {
return this->value;
}
如何使用 Google 测试框架对其进行测试?
/*
TEST(node_test_t, node_test) {
node_t<std::string, float> node;
std::string key = node.get_key();
ASSERT_STREQ(key, 0);
node.set_key("one");
ASSERT_STREQ(node.get_key(), "one");
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4);
ASSERT_EQ(node.get_value(), 2.4);
}
*/
// Updated
TEST(node_test_t, node_test)
{
node_t<std::string, float> node;
std::string key = node.get_key();
ASSERT_STREQ("0", key.c_str());
node.set_key("one");
ASSERT_STREQ("one", node.get_key().c_str());
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4f);
ASSERT_EQ(node.get_value(), 2.4f);
}
我还发现:
- gtest - testing template class
https://googletest.googlecode.com/svn/trunk/samples/sample6_unittest.cc
但是我无法编译结果。请展示一个简单的示例,说明我如何使用 Google 测试框架为此 class 编写测试。
UPD:我也试过这个:https://groups.google.com/forum/#!searchin/googletestframework/class$20template/googletestframework/wSlsjwU7vls/9ulYoFliuLgJ
template <class key_t, class value_t>
class node_testing_t : public node_t<key_t, value_t> {
public:
using node_t<key_t, value_t>::get_value;
};
TEST(node_test_case, get_value) {
node_testing_t<std::string, float> node_testing;
ASSERT_EQ(0, node_testing.get_value());
}
我也有 LNK2019
错误:
1>------ Skipped Build: Project: RUN_TESTS, Configuration: Debug Win32 ------
1>Project not selected to build for this solution configuration
2>------ Build started: Project: googlemock, Configuration: Debug Win32 ------
3>------ Build started: Project: tests, Configuration: Debug Win32 ------
3>node_test.obj : error LNK2019: unresolved external symbol "public: __thiscall node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??0?$node_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ) referenced in function "public: __thiscall node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??0?$node_testing_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ)
3>node_test.obj : error LNK2019: unresolved external symbol "public: __thiscall node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::~node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??1?$node_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ) referenced in function "public: __thiscall node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::~node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??1?$node_testing_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ)
3>node_test.obj : error LNK2019: unresolved external symbol "public: float __thiscall node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::get_value(void)" (?get_value@?$node_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAEMXZ) referenced in function "private: virtual void __thiscall node_test_case_get_value_Test::TestBody(void)" (?TestBody@node_test_case_get_value_Test@@EAEXXZ)
3>C:\Users\user\Desktop\hill-climbing\bin\tests.exe : fatal error LNK1120: 3 unresolved externals
4>------ Skipped Build: Project: ALL_BUILD, Configuration: Debug Win32 ------
4>Project not selected to build for this solution configuration
========== Build: 1 succeeded, 1 failed, 2 up-to-date, 2 skipped ==========
您是否阅读了 ASSERT_STREQ
文档?这个宏接受两个 C-strings
,你试图在第一种情况下传递它 std::string
和 int
,在第二种情况下传递 std::string
和 C-string
。顺便说一句,第一个参数是预期值,第二个参数是实际值,因此您可能需要切换提供参数的顺序。
TEST(node_test_t, node_test)
{
node_t<std::string, float> node;
std::string key = node.get_key();
ASSERT_STREQ("0", key.c_str());
node.set_key("one");
ASSERT_STREQ("one", node.get_key().c_str());
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4f);
ASSERT_EQ(node.get_value(), 2.4f);
}
P.S. 如果要比较 std::string
个对象,可以使用 EXPECT_EQ
、EXPECT_NE
等。
我在 linux 上用 gcc 4.8.4 试过你的例子,它对 link 没问题,尽管测试执行失败,因为在 node
对象构造时抛出异常因为构造函数中的 key = (key_t)0
行试图将 0
转换为 std::string
对象。
就是说,在您的情况下,MSVC linker 抱怨在 node_test.obj
文件中有未解析的对与 node_t<std::string, float>
相关的符号的引用,即构造函数、析构函数和 get_value() 成员函数。只是您测试中使用的那些。
您在测试用例范围内实例化模板,请尝试在外部范围内进行。
using node_string_float_t = node_t<std::string, float>;
TEST(node_test_t, node_test)
{
node_string_float_t node;
std::string key = node.get_key();
ASSERT_STREQ("0", key.c_str());
node.set_key("one");
ASSERT_STREQ("one", node.get_key().c_str());
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4f);
ASSERT_EQ(node.get_value(), 2.4f);
}
我有一个小class:
template <class key_t, class value_t>
class node_t {
public:
node_t();
void set_key(key_t);
key_t get_key();
void set_value(value_t);
value_t get_value();
private:
key_t key;
value_t value;
};
template <class key_t, class value_t>
node_t<key_t, value_t>::node_t() {
key = (key_t)0;
value = (value_t)0;
}
template <class key_t, class value_t>
void node_t<key_t, value_t>::set_key(key_t key) {
this->key = key;
}
template <class key_t, class value_t>
key_t node_t<key_t, value_t>::get_key() {
return this->key;
}
template <class key_t, class value_t>
void node_t<key_t, value_t>::set_value(value_t value) {
this->value = value;
}
template <class key_t, class value_t>
value_t node_t<key_t, value_t>::get_value() {
return this->value;
}
如何使用 Google 测试框架对其进行测试?
/*
TEST(node_test_t, node_test) {
node_t<std::string, float> node;
std::string key = node.get_key();
ASSERT_STREQ(key, 0);
node.set_key("one");
ASSERT_STREQ(node.get_key(), "one");
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4);
ASSERT_EQ(node.get_value(), 2.4);
}
*/
// Updated
TEST(node_test_t, node_test)
{
node_t<std::string, float> node;
std::string key = node.get_key();
ASSERT_STREQ("0", key.c_str());
node.set_key("one");
ASSERT_STREQ("one", node.get_key().c_str());
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4f);
ASSERT_EQ(node.get_value(), 2.4f);
}
我还发现:
- gtest - testing template class
https://googletest.googlecode.com/svn/trunk/samples/sample6_unittest.cc
但是我无法编译结果。请展示一个简单的示例,说明我如何使用 Google 测试框架为此 class 编写测试。
UPD:我也试过这个:https://groups.google.com/forum/#!searchin/googletestframework/class$20template/googletestframework/wSlsjwU7vls/9ulYoFliuLgJ
template <class key_t, class value_t>
class node_testing_t : public node_t<key_t, value_t> {
public:
using node_t<key_t, value_t>::get_value;
};
TEST(node_test_case, get_value) {
node_testing_t<std::string, float> node_testing;
ASSERT_EQ(0, node_testing.get_value());
}
我也有 LNK2019
错误:
1>------ Skipped Build: Project: RUN_TESTS, Configuration: Debug Win32 ------
1>Project not selected to build for this solution configuration
2>------ Build started: Project: googlemock, Configuration: Debug Win32 ------
3>------ Build started: Project: tests, Configuration: Debug Win32 ------
3>node_test.obj : error LNK2019: unresolved external symbol "public: __thiscall node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??0?$node_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ) referenced in function "public: __thiscall node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??0?$node_testing_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ)
3>node_test.obj : error LNK2019: unresolved external symbol "public: __thiscall node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::~node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??1?$node_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ) referenced in function "public: __thiscall node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::~node_testing_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>(void)" (??1?$node_testing_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAE@XZ)
3>node_test.obj : error LNK2019: unresolved external symbol "public: float __thiscall node_t<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,float>::get_value(void)" (?get_value@?$node_t@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@M@@QAEMXZ) referenced in function "private: virtual void __thiscall node_test_case_get_value_Test::TestBody(void)" (?TestBody@node_test_case_get_value_Test@@EAEXXZ)
3>C:\Users\user\Desktop\hill-climbing\bin\tests.exe : fatal error LNK1120: 3 unresolved externals
4>------ Skipped Build: Project: ALL_BUILD, Configuration: Debug Win32 ------
4>Project not selected to build for this solution configuration
========== Build: 1 succeeded, 1 failed, 2 up-to-date, 2 skipped ==========
您是否阅读了 ASSERT_STREQ
文档?这个宏接受两个 C-strings
,你试图在第一种情况下传递它 std::string
和 int
,在第二种情况下传递 std::string
和 C-string
。顺便说一句,第一个参数是预期值,第二个参数是实际值,因此您可能需要切换提供参数的顺序。
TEST(node_test_t, node_test)
{
node_t<std::string, float> node;
std::string key = node.get_key();
ASSERT_STREQ("0", key.c_str());
node.set_key("one");
ASSERT_STREQ("one", node.get_key().c_str());
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4f);
ASSERT_EQ(node.get_value(), 2.4f);
}
P.S. 如果要比较 std::string
个对象,可以使用 EXPECT_EQ
、EXPECT_NE
等。
我在 linux 上用 gcc 4.8.4 试过你的例子,它对 link 没问题,尽管测试执行失败,因为在 node
对象构造时抛出异常因为构造函数中的 key = (key_t)0
行试图将 0
转换为 std::string
对象。
就是说,在您的情况下,MSVC linker 抱怨在 node_test.obj
文件中有未解析的对与 node_t<std::string, float>
相关的符号的引用,即构造函数、析构函数和 get_value() 成员函数。只是您测试中使用的那些。
您在测试用例范围内实例化模板,请尝试在外部范围内进行。
using node_string_float_t = node_t<std::string, float>;
TEST(node_test_t, node_test)
{
node_string_float_t node;
std::string key = node.get_key();
ASSERT_STREQ("0", key.c_str());
node.set_key("one");
ASSERT_STREQ("one", node.get_key().c_str());
float value = node.get_value();
ASSERT_EQ(value, 0);
node.set_value(2.4f);
ASSERT_EQ(node.get_value(), 2.4f);
}