【问题标题】:Return reference to unique_ptr in google mock在 google mock 中返回对 unique_ptr 的引用
【发布时间】:2018-01-02 10:03:30
【问题描述】:

我在返回对 google mock 中唯一指针的引用时遇到问题。 我有一个对象 Foo,它有一个方法 opera(),我正在尝试在 google test/google mock 框架中进行测试:

class Foo {
public:
  Foo(BarInterface &bar) : bar{bar} {};
  virtual ~Foo() = default;
  void operate() { bar.getBaz()->startMeUp(); }
private:
  BarInterface &bar;
};

测试类如下所示:

using ::testing::StrictMock;
using ::testing::ReturnRef;

class FooTest : public ::testing::Test {
protected:
  StrictMock<BarMock> barMock;
  std::unique_ptr<StrictMock<BazMock>> bazMock {new StrictMock<BazMock>()}; // This might be incorrect

  Foo *foo;
  virtual void SetUp() {
    foo = new Foo(barMock);
  }

  virtual void TearDown() {
    delete foo;
  }
};

TEST_F(FooTest, BasicTest) {
  EXPECT_CALL(barMock, getBaz()).WillOnce(ReturnRef(bazMock)); // Gives compilation error
  EXPECT_CALL(*bazMock, startMeUp()); // Gives compilation error
  foo->operate();
}

如您所见,我有两个被模拟的对象,Bar 和 Baz。 Baz mock 有一个方法,startMeUp():

class BazInterface {
public:
  virtual ~BazInterface() = default;
  virtual void startMeUp() = 0;
};

class BazMock : public BazInterface {
public:
  MOCK_METHOD0(startMeUp, void());
};

Bar 方法 getBaz() 根据以下方式返回对唯一指针的引用:

class BarInterface {
public:
  virtual ~BarInterface() = default;
  virtual std::unique_ptr<BazInterface>& getBaz() = 0;
};

class BarMock : public BarInterface {
public:
  MOCK_METHOD0(getBaz, std::unique_ptr<BazInterface>&());
};

问题是(至少)我无法正确获取两个 EXPECT_CALL()。我尝试通过多种方式返回 bazMock,但总是出现编译错误。 我还尝试通过返回对 shared_ptr 甚至是普通指针的引用来简化问题,但我也无法进行编译。 有人可以帮我做对吗?

这是编译输出:

gmock-actions.h: In instantiation of 'testing::internal::ReturnRefAction<T>::Impl<F>::Result testing::internal::ReturnRefAction<T>::Impl<F>::Perform(const ArgumentTuple&) [with F = std::unique_ptr<BazInterface>&(); T = std::unique_ptr<testing::StrictMock<BazMock> >; testing::internal::ReturnRefAction<T>::Impl<F>::Result = std::unique_ptr<BazInterface>&; testing::internal::ReturnRefAction<T>::Impl<F>::ArgumentTuple = std::tuple<>]':
foo_test.cc:30:1:   required from here
gmock-actions.h:683:14: error: invalid initialization of reference of type 'testing::internal::ReturnRefAction<std::unique_ptr<testing::StrictMock<BazMock> > >::Impl<std::unique_ptr<BazInterface>&()>::Result {aka std::unique_ptr<BazInterface>&}' from expression of type 'std::unique_ptr<testing::StrictMock<BazMock> >'
   return ref_;

【问题讨论】:

  • 为什么要返回对智能指针的引用?调用者是否希望将其更改为指向另一个对象或释放它?
  • 不,它在整个“程序生命周期”中都指向同一个 Baz 对象
  • "给出编译错误",即?
  • 我现在已将编译输出添加到上述问题中。
  • @Pucko 在这种情况下,我将返回对对象本身的引用(或者可能是原始指针),而不是智能指针。当您返回对智能指针的引用时,您可以让调用者有机会重置它,这将是一个程序错误。

标签: c++ unit-testing googletest googlemock


【解决方案1】:

最好的解决方法是更改​​BarInterface 的接口以返回对BazInterface 的引用而不是引用unique_ptr。无需将指针暴露给BarInterface 用户。
如果您坚持返回对unique_ptr 的引用,请这样做:

class BarMock : public BarInterface
{
public:
    BarMock(std::unique_ptr<BazInterface> baz) {this->baz = std::move(baz);}

    override std::unique_ptr<BazInterface>& getBaz(){
        getBazWrapped();
        return baz;
    }
    MOCK_METHOD0(getBazWrapped, void());
private:
    std::unique_ptr<BazInterface> baz;
};

FooTest

BazMock * bazMock { new <StrictMock<BazMock> };
BarMock barMock { std::unique_ptr<BazInterface>(bazMock)};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多