Google test: assert on equality to one of two values
Asked Answered
N

4

9

Is there in GoogleTest something like:

ASSERT_EQ_ONE_OF_TWO(TestValue, Value1, Value2)

which tests if TestValue == Value1 || TestValue == Value2?

This variant:

ASSERT_TRUE(TestValue == Value1 || TestValue == Value2)

is OK, but it does not show in log which value TestValue has if it fails.

Nitrous answered 5/8, 2015 at 6:13 Comment(0)
T
10

Is there in GoogleTest something like

I think No.

is OK, but it does not show in log which value TestValue has if it fails.

You can add addition log information like this:

TEST (ExampleTest, DummyTest)
{
    // Arrange.
    const int allowedOne =  7;
    const int allowedTwo = 42;
    int real             =  0;
    // Act.
    real = 5;
    // Assert.
    EXPECT_TRUE (real == allowedOne || real == allowedTwo)
            << "Where real value: "   << real
            << " not equal neither: " << allowedOne
            << " nor: "               << allowedTwo << ".";
}

This code will be produce the following log when fails:

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ExampleTest
[ RUN      ] ExampleTest.DummyTest
/home/gluttton/ExampleTest.cpp:13: Failure
Value of: real == allowedOne || real == allowedTwo
  Actual: false
Expected: true
Where real value: 5 not equal neither: 7 nor: 42.
[  FAILED  ] ExampleTest.DummyTest (0 ms)
[----------] 1 test from ExampleTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] ExampleTest.DummyTest
Togetherness answered 5/8, 2015 at 7:13 Comment(0)
T
10

I just found a nicer solution which I wanted to share, but Andre Holzner already proposed it in this answer.

That solution has all the pros of mine but none of the cons. And it is also more flexible as it supports matchers, so you can do stuff like this:

EXPECT_THAT(someString, AnyOf(StartsWith("foo"), StartsWith("bar")));

This will give an output similar to this (created with GTest 1.10)

error: Value of: someString
Expected: (starts with "foo") or (starts with "bar")
  Actual: "baz"

You can use EXPECT_THAT() in combination with a container and the Contains() matcher to achieve this:

EXPECT_THAT((std::array{ Value1, Value2 }), Contains(TestValue));

Note that the braces after array are needed for list initialization and the parentheses around array are needed, because macros (such as EXPECT_THAT()) do not understand braces and would otherwise interpret the two arguments as three arguments.

This will give an output similar to this (created with GTest 1.10)

error: Value of: (std::array{ Value1, Value2 })
Expected: contains at least one element that is equal to 42
  Actual: { 12, 21 }

Pro:

  • Prints all values
  • one-liner
  • works out of the box

Con:

  • Finding the value of TestValue in the output is not easy
  • Syntax is not straight forward
  • Modern compiler features are needed
    • C++11 is needed due to std::array and list initialization (still not available everywhere)
    • C++17 is needed due to CTAD, use std::initializer_list<T>{ ... } on C++11/14. Alternatively a free function can be used to deduce size and type of the array.
Tenpin answered 2/2, 2021 at 13:19 Comment(1)
Small note for future visitors: This requires including gmock/gmock.h instead of or in addition to gtest/gtest.hSought
S
1

You can use the following:

ASSERT_THAT(TestValue, AnyOf(Value1, Value2));

or if you need floating point matching with doubles:

ASSERT_THAT(TestValue, AnyOf(DoubleEq(Value1), DoubleEq(Value2)));
Saddletree answered 21/2, 2023 at 17:2 Comment(0)
O
0

I haven't found anything "baked in" to do what you are asking, but a predicate assertion should be able to handle the type of assertion you are asking for. Additionally, GoogleTest will automatically print out the arguments and their values when the assertion does fail.

The assertion you would use in your case is

ASSERT_PRED3(<insert predicate>, TestValue, Value1, Value2)

The predicate is a function or functor that returns bool, where false fails the assertion. For your predicate, you could use a function like the following:

bool OrEqual(int testValue, int option1, int option2)
{
  if (testValue == option1 ||
      testValue == option2)
  {
    return true;
  }
  else
  {
    return false;
  }
}

Of course, this is a simple example. Since you can provide any function or functor that takes the provided arguments, there is plenty that you can do with predicate assertions.

Here is the documentation: https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#predicate-assertions-for-better-error-messages

Omphalos answered 25/11, 2019 at 20:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.