【问题标题】:c++ GMock SetArgReferee as CStringArrayc++ GMock SetArgReferee as CStringArray
【发布时间】:2022-07-26 05:42:23
【问题描述】:

在 MFC 中使用 c++11,并尝试使用 gtest 1.7 创建一些单元测试,我遇到了一个问题。我想在不更改下面方法的声明或定义的情况下模拟一个讨厌的方法。

virtual bool  getValue(CStringArray& valueOut) const;

Mocking 很简单,MOCK_CONST_METHOD1(getValue,bool(CStringArray&)); 会为我做这件事。但是,在测试用例中使用,我无法使其工作。
测试用例的相关部分:

CStringArray localArray;
localArray.Add("Only One Element");
EXPECT_CALL(object, getValue(_)).WillOnce(DoAll(SetArgReferee<0>(localArray), Return(true)));

这给了我一个编译错误,因为CStringArray(派生自CObject)是不可复制、不可移动的对象。我的问题是,
如何仅使用模拟函数来更改返回数组?

我知道我可以创建一个混合模拟,用一个真正的函数来构建数组,但是我很难为每个测试用例添加自定义元素。比如:

struct MockNastyObject : public NastyObject {
    MOCK_CONST_METHOD1(getValueMock, bool(CStringArray&));
    virtual bool getValue(CStringArray& arr) const override{
        arr.Add("Element1");
        getValueMock(arr);
    }
};

这种方法可行,因为我可以为 getValueMock 设置期望值并使用非模拟方法更改数组。

【问题讨论】:

  • 使用 MFC 进行单元测试?!没看过。你想达到什么目标?
  • 我有这个getValue 函数,它使用数据库——我在测试中不能也不想。它返回我提供的参数中的值,在本例中为CStringArray。哦,如果成功则返回true。所以,我想在每个测试中用不同的假值填充该数组。

标签: c++ mfc googletest googlemock


【解决方案1】:

不知道你想实现什么——第一个代码sn-p是赋值,第二个代码sn-p是元素加法。至于第二个,它可以通过没有自定义专门操作的 lambda 来完成:

CStringArray localArray;
localArray.Add("Only One Element");
EXPECT_CALL(object, getValue(_)).WillOnce(DoAll(
  WithArg<0>([&localArray](CStringArray& a) { a.Add(localArray[0]); }),
  Return(true)));

或没有localArray的简化:

EXPECT_CALL(object, getValue(_)).WillOnce(DoAll(
  WithArg<0>([](CStringArray& a) { a.Add("Only One Element"); }),
  Return(true)));

【讨论】:

    【解决方案2】:

    一种方法是创建一个gmock action,如下所示。

    首先,您需要创建一个辅助方法,该方法将在设置期望时填充您的数组(文档中提到的类外或测试用例)。然后设置一个适当的EXPECT_CALL 使其工作。

    struct MockNastyObject : public NastyObject {
        MOCK_CONST_METHOD1(getValue, bool(CStringArray&));
    };
    
    ACTION_P(AddParamToCArray, param) { arg0.Add(param); }
    
    TEST(testOne, populateTest)
    {
        MockNastyObject myMock;
        EXPECT_CALL(myMock, getValue(_)).WillOnce(DoAll(
            WithArg<0>(AddParamToCArray("First element")),
            WithArg<0>(AddParamToCArray("Second element")),
            Return(true)));
        ...
    }
    

    如您所见,这不仅对 CStringArray 有用,而且对任何支持 Add 的容器都有用。
    最初的问题是关于SetArgReferee,尽管解决方案没有使用它。

    另外,another approach 也很有用。

    【讨论】:

      猜你喜欢
      • 2021-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多