我有一些单元测试来验证某些值是否等于0。在某些情况下,它们应该是0,而在某些情况中,它们不是。
如下所示:testA
期望valueA
不包含0,而testB
期望valueB
不包含0。
我想做的是以某种方式将验证部分封装在一个函数中,这样我就不会为每个成员调用EXPECT_NE
/EXPECT_EQ
,而是只调用一个负责验证部分的函数。
TEST(UnitTest, testA)
{
Object object;
// do stuff that modified object's values
EXPECT_NE(object.valueA, 0);
EXPECT_EQ(object.valueB, 0);
}
TEST(UnitTest, testB)
{
Object object;
// do stuff that modified object's values
EXPECT_EQ(object.valueA, 0);
EXPECT_NE(object.valueB, 0);
}
这是我想出来的,但有点太冗长了。想知道是否有更好的方法?
void Validate(Object* obj, bool valA, bool valB)
{
// verify valueB
if (valA)
{
EXPECT_EQ(object->valueA, 0);
}
else
{
EXPECT_NE(object->valueA, 0);
}
// verify valueB
if (valB)
{
EXPECT_EQ(object->valueB, 0);
}
else
{
EXPECT_NE(object->valueB, 0);
}
}
TEST(UnitTest, testA)
{
Object object;
// do stuff that modified object's values
Validate(&object, false, true);
}
TEST(UnitTest, testB)
{
Object object;
// do stuff that modified object's values
Validate(&object, true, false);
}
具有FieldsAre
和结构化绑定
使用C++17和最新的GoogleTest版本(>=v1.12.0(,您可以简单地使用FieldsAre()
,以防Object
允许结构化绑定(请参阅实际示例(:
using ::testing::FieldsAre;
using ::testing::Eq;
using ::testing::Ne;
struct Object
{
int valueA;
int valueB;
};
TEST(UnitTest, testA)
{
Object object{42,0};
EXPECT_THAT(object, FieldsAre(Ne(0), Eq(0)));
}
TEST(UnitTest, testB)
{
Object object{0, 42};
EXPECT_THAT(object, FieldsAre(Eq(0), Ne(0)));
}
搭配火柴
否则(如果你的GoogleTest太旧或者Object
不允许结构化绑定(,你可以写一个类似匹配器的简单函数:
using ::testing::Field;
using ::testing::AllOf;
template <class M1, class M2>
auto MatchesValues(M1 m1, M2 m2)
{
return AllOf(Field(&Object::valueA, m1), Field(&Object::valueB, m2));
}
并像FieldsAre
一样使用它(实际示例(:
TEST(UnitTest, testA)
{
Object object{42,0};
EXPECT_THAT(object, MatchesValues(Ne(0), Eq(0)));
}
TEST(UnitTest, testB)
{
Object object{0, 42};
EXPECT_THAT(object, MatchesValues(Eq(0), Ne(0)));
}
使用自定义匹配器
如注释中所述,您的原始Object
是一个模板,在这种情况下不能使用Field
。在这种情况下,你可以像这样写一个合适的客户匹配器(示例(:
template<typename T>
struct Object
{
int valueA;
int valueB;
T otherStuff;
Object(int a, int b) : valueA(a), valueB(b) {}
};
MATCHER_P2(MatchesValues, m1, m2, "")
{
return ExplainMatchResult(m1, arg.valueA, result_listener)
&& ExplainMatchResult(m2, arg.valueB, result_listener);
}
TEST(UnitTest, testA)
{
Object<int> object{42,0};
EXPECT_THAT(object, MatchesValues(Ne(0), Eq(0)));
}