GoogleTest 使用指南 |自定义断言
- GoogleTest 使用指南 |自定义断言
GoogleTest 使用指南 |自定义断言
在某些测试场景中,内置断言可能无法满足特定需求。此时,开发者可以定义自定义断言,以实现更灵活和精准的测试验证。
test_custom_assertion.cpp:
#include"gtest/gtest.h"#include<iostream>#include<sstream>#include<string>#include<vector>namespace{structAddress{std::string city;std::string zip_code;};structUserProfile{intid;std::string name;intage;boolactive;Address address;std::vector<std::string>roles;};std::stringFormatRoles(conststd::vector<std::string>&roles){std::ostringstream stream;stream<<"[";for(std::size_t i=0;i<roles.size();++i){if(i>0){stream<<", ";}stream<<roles[i];}stream<<"]";returnstream.str();}::testing::AssertionResultUserProfileMatches(constUserProfile&actual,constUserProfile&expected){std::ostringstream failures;if(actual.id!=expected.id){failures<<"id: expected "<<expected.id<<", actual "<<actual.id<<"\n";}if(actual.name!=expected.name){failures<<"name: expected "<<expected.name<<", actual "<<actual.name<<"\n";}if(actual.age!=expected.age){failures<<"age: expected "<<expected.age<<", actual "<<actual.age<<"\n";}if(actual.active!=expected.active){failures<<"active: expected "<<expected.active<<", actual "<<actual.active<<"\n";}if(actual.address.city!=expected.address.city){failures<<"address.city: expected "<<expected.address.city<<", actual "<<actual.address.city<<"\n";}if(actual.address.zip_code!=expected.address.zip_code){failures<<"address.zip_code: expected "<<expected.address.zip_code<<", actual "<<actual.address.zip_code<<"\n";}if(actual.roles!=expected.roles){failures<<"roles: expected "<<FormatRoles(expected.roles)<<", actual "<<FormatRoles(actual.roles)<<"\n";}conststd::string message=failures.str();if(message.empty()){return::testing::AssertionSuccess();}return::testing::AssertionFailure()<<"UserProfile mismatch:\n"<<message;}boolContains(conststd::string&text,conststd::string&expected){returntext.find(expected)!=std::string::npos;}}// namespaceTEST(CustomAssertionTest,VerifiesComplexObjectProperties){constUserProfile actual{1001,"Alice",28,true,{"Shanghai","200000"},{"admin","editor"}};constUserProfile expected{1001,"Alice",28,true,{"Shanghai","200000"},{"admin","editor"}};EXPECT_TRUE(UserProfileMatches(actual,expected));}TEST(CustomAssertionTest,ReportsAllMismatchedProperties){constUserProfile actual{1002,"Bob",30,false,{"Beijing","100000"},{"viewer"}};constUserProfile expected{1001,"Alice",28,true,{"Shanghai","200000"},{"admin","editor"}};const::testing::AssertionResult result=UserProfileMatches(actual,expected);conststd::string message=result.message();std::cout<<message;EXPECT_FALSE(result);EXPECT_TRUE(Contains(message,"id: expected 1001, actual 1002"));EXPECT_TRUE(Contains(message,"name: expected Alice, actual Bob"));EXPECT_TRUE(Contains(message,"age: expected 28, actual 30"));EXPECT_TRUE(Contains(message,"address.city: expected Shanghai, actual Beijing"));EXPECT_TRUE(Contains(message,"roles: expected [admin, editor], actual [viewer]"));}TEST(CustomAssertionTest,DISABLED_ShowsGoogleTestFailureMessage){constUserProfile actual{1002,"Bob",30,false,{"Beijing","100000"},{"viewer"}};constUserProfile expected{1001,"Alice",28,true,{"Shanghai","200000"},{"admin","editor"}};EXPECT_TRUE(UserProfileMatches(actual,expected));}这个例子定义了一个复杂对象:
UserProfile { id name age active address.city address.zip_code roles }并定义了自定义断言:
::testing::AssertionResultUserProfileMatches(constUserProfile&actual,constUserProfile&expected)它会一次性检查多个属性;如果不匹配,会把所有差异都写进失败信息。
运行测试,会打印 mismatch message:
自定义断言的应用场景:
- 复杂对象验证:验证对象的多个属性是否符合预期。
- 自定义逻辑验证:根据特定业务逻辑定义断言条件。
- 增强错误信息:在断言失败时提供详细的错误信息,便于快速定位问题。