This repository contains a common interface for the test utilities used by the different C++ projects of Systelab organization.
Entity comparators allow adding an equality expectation for Google Test over two model entities. When the entities are different, the comparator will provide a detailed message with the first difference found. So, they are very useful for troubleshooting failures on unit tests or integration tests.
For instance, given a Patient model entity:
struct Patient
{
int id;
std::string name;
int age;
bool male;
double height;
};An entity comparator can be defined by implementing the operator():
namespace systelab { namespace test_utility {
template <>
testing::AssertionResult EntityComparator::operator() (const Patient& expected, const Patient& actual) const
{
if (expected.id != actual.id)
{
return AssertionFailure() << "Different value for id: expected=" << expected.id
<< ", actual=" << actual.id;
}
if (expected.name != actual.name)
{
return AssertionFailure() << "Different value for name: expected=" << expected.name
<< ", actual=" << actual.name;
}
...
return AssertionSuccess();
}Then it can be used on a unit test as follows:
TEST_F(PatientTest, testPatientsAreEqual)
{
Patient expectedEntity = {1, "Nicolas Cage", 55, 1.81, true};
Patient actualEntity = {1, "Nicole Kidman", 55, 1.81, true};
ASSERT_TRUE(systelab::test_utility:EntityComparator()(expectedEntity, actualEntity));
}The execution of this test should print something like:
Different value for name: expected=Nicolas Cage, actual=Nicole KidmanBoilerplate code on entity comparators implementations can be reduced significantlly by using some helper macros. They allow performing simple comparisons within a single line of code:
// Compares an expression result by asserting it to be equal
COMPARATOR_ASSERT_EQUAL(expected, actual, name);
COMPARATOR_ASSERT_EQUAL(expected, actual, age);
COMPARATOR_ASSERT_EQUAL(expected, actual, male);
// Compares double/float expression result by asserting it to be near (using a given tolerance)
COMPARATOR_ASSERT_NEAR(expected, actual, height, 1e-4); Entity comparators can also be used when checking arguments for Google Mock function call expectations. Using the isEqualTo matcher, wrong method invokations can be troubleshooted:
Patient expectedEntity = {2, "Isabel Pantoja", 62, 1.75, false};
EXPECT_CALL(service, createPatient(isEqualTo(expectedPatient)));It is possible to configure an entity comparator to exclude the comparison of a certain members. In order to do so, a configuration object needs to be provided when invoking the () operator:
systelab::test_utilitiy::EntityComparatorConfiguration configuration({"id"});
ASSERT_TRUE(systelab::test_utility:EntityComparator(configuration)(expectedEntity, actualEntity));Aside from that, the implementation of the comparator needs to name the comparisons susceptible to be excluded. This can be achieved either by directly accessing to the configuration object:
if (!m_configuration.isMemberExcluded("id"))
{
if (expected.id != actual.id)
{
return AssertionFailure() << "Different value for id: expected=" << expected.id
<< ", actual=" << actual.id;
}
}Or by using the COMPARATOR_ASSERT_EQUAL_WITH_EXCLUSION helper macro (which is much shorter):
COMPARATOR_ASSERT_EQUAL_WITH_EXCLUSION(expected, actual, id, "id");