3

In gmock is there anyway to match against a type rather than value? The class is something like:

struct Blob {
    template<class T> bool is(); // if blob holds data of type T
    template<class T> T get(); // get data as type T
}

My matcher looks like this:

MATCHER_P(BlobIs, T, "") {
    return arg->is<T>();
}

But the build failed with:

error: expected primary-expression before ')' token
273K
  • 29,503
  • 10
  • 41
  • 64
fluter
  • 13,238
  • 8
  • 62
  • 100
  • Did you add a template ? Also, shouldn't your matcher have a name ? Right now it is an empty string I believe – Arne J Aug 02 '19 at 05:15
  • MATCHER_P is a macro, the string is not name, it's a description. – fluter Aug 02 '19 at 06:13
  • Did you tried something like `return arg->is();`? Passing to matcher value of type T, rather than just type. – sklott Aug 02 '19 at 06:50
  • T does not have default constructor, so i didn't try that, because i just want to have a matcher to assert on types. – fluter Aug 02 '19 at 08:53
  • "T does not have default constructor" - it doesn't matter you can pass pointer, e.g. `static_cast(nullptr)` and then get type of pointer. You can't pass just "type" where "value" is expected. You either need to implement your custom matcher without using macros, i.e. do something similar what `MATCHER_P()` does, or find some wrokaround. – sklott Aug 02 '19 at 09:54
  • exactly i was asking how to implement with MATCHER_P, i don't want to pass a value here. – fluter Aug 02 '19 at 13:37

2 Answers2

3

You can use wildcard matchers A<type> and An<type> (documentation):

EXPECT_CALL(foo, Describe(A<const char*>()))
    .InSequence(s2)
    .WillOnce(Return("dummy"));
pooya13
  • 2,060
  • 2
  • 23
  • 29
  • 1
    Link seems to be broken in the answer, but you can read about it here now: http://google.github.io/googletest/reference/matchers.html#wildcard – Jordfräs May 03 '23 at 05:37
2

You cannot pass type as parameter to any function - including those generated by MATCHER_P macro.

But you can pass lambda(function object) that will use correct type.

Like here:

MATCHER_P(BlobIsImpl, isForForType, "") {
    return isForType(arg);
}

With the following function template - you will achieve the desired goal:

template <typename T>
auto BlobIs()
{
     auto isForType = [](Blob& arg) -> bool 
     { 
         return arg->template is<T>();
     };
     return BlobIsImpl(isForType); 
}

Use like this: BlobIs<SomeType>()

2 more issues:

  1. You have to use template keyword to specify that is is a function template. More info here
  2. You should define is as const function.
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112