On Fri, May 1, 2009 at 2:05 AM, Michael Williamson <find...@gmail.com> wrote:
> Does google mock support optional parameters?
> (I believe they're not allowed in google coding standards ...)
>
> I'm mocking a 3rd party library class.
> I use an "adapter" to wrap it, and am trying to keep the function signatures
> equivalent.
>
> The original library method:
> virtual SceneNode* createChildSceneNode(
> const Vector3& translate = Vector3::ZERO,
> const Quaternion& rotate = Quaternion::IDENTITY );
>
> My adapter equivalent:
> virtual SceneNodeAdapter* createChildSceneNode(
> const Ogre::Vector3& translate = Ogre::Vector3::ZERO,
> const Ogre::Quaternion& rotate = Ogre::Quaternion::IDENTITY ) =
> 0;
Since *you* are writing the wrapper and *you* control the code using
the wrapper, you don't have to make your wrapper accept default
arguments just because the original method does. Is that an option?
If you really need default arguments for your mock method, you can do
it. I'll show you how below.
> And I derive from the adapter to produce the mock:
> MOCK_METHOD2( createChildSceneNode, SceneNodeAdapter* (
> const Ogre::Vector3& translate = Ogre::Vector3::ZERO,
> const Ogre::Quaternion& rotate = Ogre::Quaternion::IDENTITY ) );
>
> This last produces an error:
> ======
> gmock-spec-builders.h(1325) : error C2383: 'F' : default-arguments are not
> allowed on this symbol
> 1> c:\devroot\gmock-1.1.0\include\gmock\gmock-spec-builders.h(1325) :
> see reference to class template instantiation
> 'testing::internal::MockSpec<F>' being compiled
> 1> with
> 1> [
> 1> F=OgreTestSeams::SceneNodeAdapter *(const Ogre::Vector3
> &,const Ogre::Quaternion &)
> ======
>
> If optional params are not supported by gmock, is a solution to make my
> adapter instead overload createChildSceneNode with 0, 1 and 2 argument
> versions?
The method itself shouldn't care about whether it was invoked with
default arguments or explicit arguments. Therefore using 3 overloaded
mock methods isn't a very good solution. It makes it harder to set
expectations on the method.
I suggest this pattern:
MOCK_METHOD2(createChildSceneNodeImpl, SceneNodeAdapter* (
const Ogre::Vector3& translate,
const Ogre::Quaternion& rotate) );
virtual SceneNodeAdapter* createChildSceneNode(
const Ogre::Vector3& translate = Ogre::Vector3::ZERO,
const Ogre::Quaternion& rotate = Ogre::Quaternion::IDENTITY ) {
return createChildSceneNodeImpl(translate, rotate);
}
Then, your production code will use createChildSceneNode() as usual.
In your tests you would write:
EXPECT_CALL(mock_foo, createChildSceneNodeImpl(_, _))...;
--
Zhanyong
On second thought, I am not sure what you are trying to achieve.
Your mock class implements an interface, and createChildSceneNode() is
in that interface. Your production code talks to that interface. As
long as you specify the default arguments in the interface, your
production code should be able to use the default arguments. There's
no need to make the derived mock class specify the default arguments
again.
class Base {
public:
...
// Specify the default arguments in the interface.
virtual SceneNodeAdapter* createChildSceneNode(
const Ogre::Vector3& translate = Ogre::Vector3::ZERO,
const Ogre::Quaternion& rotate = Ogre::Quaternion::IDENTITY) = 0;
};
class Mock : public Base {
public:
// Not in the implementation.
MOCK_METHOD2(createChildSceneNode, SceneNodeAdapter*(
const Ogre::Vector3& translate,
const Ogre::Quaternion& rotate));
};
// In your production code:
Base* base = ...;
base->createChildSceneNode();
// In your tests:
Mock m;
EXPECT_CALL(m, createChildSceneNode(_, _))...;
Would this work for you?
2009/5/1 Zhanyong Wan (λx.x x) <w...@google.com>:
--
Zhanyong