14

我有一个将布尔值作为参考参数并返回整数的类:

class Foo
{
  public:
    Bar my_bar;
    virtual int myMethod(bool &my_boolean) = 0;
}

/*...*/

int Foo::myMethod(bool &my_boolean){
  if (my_bar == NULL){
    my_boolean = false;
    return -1;
  }
  else{
    my_boolean = true;
    return 0;
  }

}

我为这个类创建了一个模拟:

class MockFoo : public Foo
{
   MOCK_METHOD1(myMethod,int(bool &my_boolean));
}

我在如何设置此类函数的期望时遇到问题,因为我需要将返回值引用参数设置为特定值才能正确创建我的单元测试。如何使用 gmock 处理这种函数?我尝试遵循我认为是文档中的解决方案:

using ::testing::SetArgPointee;

class MockMutator : public Mutator {
  public:
  MOCK_METHOD2(Mutate, void(bool mutate, int* value));
  ...
};
  ...

MockMutator mutator;
EXPECT_CALL(mutator, Mutate(true, _))
  .WillOnce(SetArgPointee<1>(5));

但是要么我不理解这个例子,要么它不适用于这个案例。以前有没有人处理过这种情况?

提前致谢。

4

1 回答 1

18

你的问题很难回答!来自谷歌模拟“烹饪书”的样本也是如此。

您是想在Foo::myMethod()模拟类中重用实现,还是只想模拟特定调用情况的副作用(返回值并由 ref 参数更改)?

模拟类通常用于替换/模拟您的Foo类,而不是直接继承它或它的行为。不知道您为纯方法定义这种“默认”行为的方式是否有效,但对此表示怀疑。你可以简单地省略= 0then。更好的方法是分离出一个真正的接口声明,如:

struct IFoo
{
    virtual int myMethod(bool &my_boolean) = 0;
    virtual ~IFoo() {}
};

class Foo : public IFoo
{
    // ...
};

class MockFoo : public IFoo
{
   MOCK_METHOD1(myMethod,int(bool &my_boolean));
};

如果您遇到后一种情况,您应该使用testing::Return(value)and testing::SetArgReferee<N>(value)(在非常有用的“备忘单”中找到)。

您的期望调用应如下所示:

MockFoo foo;

// Expect call to myMethod() return -1 and set the by ref argument to true
EXPECT_CALL(foo, myMethod(_))
  .WillOnce(DoAll(SetArgReferee<0>(true),Return(-1)));

// Expect call to myMethod() return 0 and set the by ref argument to false
EXPECT_CALL(foo, myMethod(_))
  .WillOnce(DoAll(SetArgReferee<0>(false),Return(0)));

如果您真的想重用原始类逻辑,myMethod()请查看“将调用委托给父类”,resp。'将调用委托给真实对象'

于 2013-06-21T16:32:28.193 回答