c++ - 如何期待稍后创建的指针参数

标签 c++ unit-testing mocking googletest googlemock

我有这样的组 -> 要添加/删除的元素,代码片段:

// production code:
Group::add(Element* e) {...};
Group::remove(Element* e) {...};
ElementDerived::ElementDerived(Group* group){ group->add(this);}
ElementDerived::~ElementDerived(Group* group){ group->remove(this);}

每当我想测试类 ElementDerived 时,我必须在设置/拆卸中执行以下操作。但是,如何在没有 _ 的情况下显式设置参数期望值?

// test code:
struct Test_ElementDerived : public ::testing::Test {
  void SetUp() override {
    ElementDerived* p = nullptr;
    EXPECT_CALL(group, add(_)) // how to set expection on the pointer argument?
      .WillOnce(Invoke([&p](auto base_ptr) {
        p = static_cast<ElementDerived*>(base_ptr);
      }));
    sut = std::make_unique<ElementDerived>(&group);
  }
  void TearDown() override {
    EXPECT_CALL(group, remove(sut.get()));
  }
  MockGroup group{};
  std::unique_ptr<ElementDerived> sut;
};

最佳答案

你可以这样做:

 Element* p = nullptr;
 EXPECT_CALL(group, add(_)).WillOnce(SaveArg<0>(&p));
 sut = std::make_unique<ElementDerived>(&group);
 ASSERT_EQ(p, static_cast<Element*>(sut.get()));

这与您刚才所做的没有太大区别。要用一些匹配器替换 _ - 你必须知道指针 - 实现这一点的唯一方法是使用新的放置:

 struct DestructCaller {
     template <typename T> void operator()(T* ptr)
     {
        if (ptr) ptr->~T();
     }
 };
 std::aligned_storage_t<sizeof(ElementDerived), alignof(ElementDerived)> sut_storage;
 std::unique_ptr<ElementDerived, DestructCaller> sut;

 void SetUp() override
 {

     EXPECT_CALL(group, add((ElementDerived*)&sut_storage));
     sut.reset(new (&sut_storage) ElementDerived(&group));
 }

或无限制 union 的类似概念:

 union
 {
     ElementDerived sut;
 };

 void SetUp() override
 {

     EXPECT_CALL(group, add(&sut));
     new (&sut) ElementDerived(&group);
 }
 void TearDown() override
 {

     EXPECT_CALL(group, remove(&sut));
     sut.~ElementDerived();
 }

在我个人看来 - 使用 SaveArg 和 ASSERT_EQ 的方法更具可读性。

关于c++ - 如何期待稍后创建的指针参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42348325/

相关文章:

testing - Golang 与 Martini : Mock testing example

c++ - 在运行时反复使用和对象的最佳实践是什么

c++ - 我的字符串末尾有 4 个相同的垃圾字符

c# - 对 SqlCommand 的扩展方法进行单元测试的方法

Python Mocking - 如何修补函数内的变量

java - Vert.x 单元测试不执行

C++ Boost 如何将 C++ 对象序列化到共享内存并在另一个应用程序中重新创建它

c++ - 为什么 clang 会使我的简单阶乘函数过于复杂?

perl - 如何在Perl中伪造STDIN?

c# - 使用 List<string> 类型作为 DataRow 参数