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 myMet开发者_如何学Pythonhod 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 );
}
};
精彩评论