English 中文(简体)
How to mock templated methods using Google Mock?
原标题:

I am trying to mock a templated method.

Here is the class containing the method to mock :

class myClass
{
public:
    virtual ~myClass() {}

    template<typename T>
    void myMethod(T param);
}

How can I mock the method myMethod using Google Mock?

最佳回答

In previous version of Google Mock you can only mock virtual functions, see the documentation in the project s page.

More recent versions allowed to mock non-virtual methods, using what they call hi-perf dependency injection.

As user @congusbongus states in the comment below this answer:

Google Mock relies on adding member variables to support method mocking, and since you can t create template member variables, it s impossible to mock template functions

A workaround, by Michael Harrington in the googlegroups link from the comments, is to make specialized the template methods that will call a normal function that can be mocked. It doesn t solve the general case but it will work for testing.

struct Foo
{
    MOCK_METHOD1(GetValueString, void(std::string& value));

    template <typename ValueType>
    void GetValue(ValueType& value); 

    template <>
    void GetValue(std::string& value) {
        GetValueString(value);
    } 
};
问题回答

Here is the original post again with comments to aid in understanding:

    struct Foo 
    { 
        // Our own mocked method that the templated call will end up calling.
        MOCK_METHOD3(GetNextValueStdString, void(const std::string& name, std::string& value, const unsigned int streamIndex)); 

        // If we see any calls with these two parameter list types throw and error as its unexpected in the unit under test.
        template< typename ValueType > 
        void GetNextValue( const std::string& name, ValueType& value, const unsigned int streamIndex ) 
        { 
            throw "Unexpected call."; 
        } 
        template< typename ValueType > 
        void GetNextValue( const std::string& name, ValueType& value ) 
        { 
            throw "Unexpected call."; 
        } 

        // These are the only two templated calls expected, notice the difference in the method parameter list. Anything outside
        // of these two flavors is considerd an error.
        template<> 
        void GetNextValue< std::string >( const std::string& name, std::string& value, const unsigned int streamIndex ) 
        { 
            GetNextValueStdString( name, value, streamIndex ); 
        } 
        template<> 
        void GetNextValue< std::string >( const std::string& name, std::string& value ) 
        { 
            GetNextValue< std::string >( name, value, 0 ); 
        } 
    }; 

Here a solution that doesn t require to implement each template instantiation manually, this is especially helpful if there are a lot of different template instantiations.


struct Foo
{
  template <typename T>
  struct FooImpl
  {
    MOCK_METHOD(void, myMethod, (const T& value), ());
  };

  template <typename T>
  void myMethod(const T& value)
  {
    GetMock<T>()->myMethod(value);
  }

  template <typename T>
  std::shared_ptr<FooImpl<T>> GetMock()
  {
    std::shared_ptr<FooImpl<T>> result;
    std::shared_ptr<void> voidValue;
    if (!(voidValue = mCachedImpls[typeid(T).name()])
    {
      result = std::make_shared<FooImpl<T>>();
      mCachedImpls[typeid(T).name()] = std::reinterpret_pointer_cast<void>(result);
    }
    else
    {
      result = std::reinterpret_pointer_cast<FooImpl<T>>(voidValue);
    }

    return result;
  }

private:
  std::unordered_map<std::string, std::shared_ptr<void>> mCachedImpls;
};

Mock can then be prepared like this:

Foo foo;
EXPECT_CALL(*(foo.GetMock<int>()), myMethod(_)).Times(1);




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签