我有一个单元测试,用于验证某些成员值(valueA
、valueB
(是否等于0。正在测试的对象,即Object
是一个模板,我希望实现的是:
将验证部分封装在一个函数中,这样我就不会为每个成员值调用EXPECT_NE/EXPECT_EQ
,而是只调用一个负责验证的函数
这是原始片段:
template<typename T>
struct Object
{
struct Values
{
int valueA;
int valueB;
};
Values values = {};
T otherStuff;
void setValues(int valueA, int valueB)
{
values.valueA = valueA;
values.valueB = valueB;
}
};
TEST(UnitTest, testA)
{
Object<int> object;
// do stuff that modified object's values via setValues()
EXPECT_NE(object.values.valueA, 0);
EXPECT_EQ(object.values.valueB, 0);
}
以下是我想到的,但我得到了以下错误
gmock-matchers.h:2074:31: error: no matching function for call to 'testing::internal::FieldMatcher<Object<int>::Values, int>::MatchAndExplainImpl(std::integral_constant<bool, false>::type, const Object<int>&, testing::MatchResultListener*&) const'
2074 | return MatchAndExplainImpl(
| ~~~~~~~~~~~~~~~~~~~^
2075 | typename std::is_pointer<typename std::remove_const<T>::type>::type(),
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2076 | value, listener);
如果我在结构之外使用一个成员变量,即MatchesStruct
中的testVar
,它会编译得很好。为什么用结构成员抱怨?
using ::testing::Eq;
using ::testing::Ne;
using ::testing::Field;
using ::testing::AllOf;
template<typename T>
struct Object
{
int testVar;
struct Values
{
int valueA;
int valueB;
};
Values values = {};
T otherStuff;
void setValues(int valueA, int valueB)
{
values.valueA = valueA;
values.valueB = valueB;
}
};
template <typename T, class M1, class M2>
auto MatchesStruct(M1 m1, M2 m2)
{
return AllOf(Field(&Object<T>::Values::valueA, m1),
Field(&Object<T>::Values::valueB, m2));
}
TEST(UnitTest, testA)
{
Object<int> object;
// do stuff that modified object's values via setValues()
EXPECT_THAT(object, MatchesStruct<int>(Ne(0), Eq(0)));
}
这是的活样本
这与您几个小时前问的问题几乎相同,实际上是基于我在那里的初始答案,但有一点不同,这里Object
是一个模板,其成员valueA
和valueB
在另一个结构中。不能像您尝试的那样在成员变量中形成指向成员的成员指针(即,C++标准不允许使用&Object<T>::Values::valueA
(,因此Field
不能以这种方式使用。
无论如何,这个问题的答案与我在另一篇文章中的答案几乎相同(在你在评论中说你的Object
是一个模板后,我刚刚修改了它(:用MATCHER_P2
写一个合适的匹配器,就像这样(示例(:
template<typename T>
struct Object
{
int ran;
struct Values
{
int valueA = 42;
int valueB = 0;
};
Values values = {};
T otherStuff;
};
MATCHER_P2(MatchesStruct, m1, m2, "")
{
return ExplainMatchResult(m1, arg.values.valueA, result_listener)
&& ExplainMatchResult(m2, arg.values.valueB, result_listener);
}
TEST(UnitTest, testA)
{
Object<int> object;
EXPECT_THAT(object, MatchesStruct(Ne(0), Eq(0)));
}