【问题标题】:Can I use google mocks to check method parameters without setting an expectation in advance?我可以在不提前设置期望的情况下使用 google mocks 来检查方法参数吗?
【发布时间】:2015-10-02 16:10:57
【问题描述】:

我有一种情况,我想检查是否使用参数 X 调用了一个模拟对象方法,但测试仅在调用模拟之后 才能访问 X,所以我无法设置预先一个 EXPECT_CALL。

例如

// The class I'm testing.
class Maker
{
    void register(Listener& lis);
    Obj& make()
    {
        // make new Obj o
        // call created(o) on registered Listener  
        // return o
    }
}

class Listener
{
    virtual void created(Obj& o) = 0;
}

// The test
Listener lis;
Maker maker;
maker.register(lis);

Obj& o = maker.make();

// Check that lis was invoked using param o...how?

我可以用 google mocks 做到这一点吗?使用 google mocks 最优雅/可读的方式是什么?

显然我可以制作自己的 MockListener 来记录调用参数,而不是使用谷歌模拟。但我希望 google mocks 会提供一种更易读的机制,类似于 EXPECT_CALL。

【问题讨论】:

    标签: c++ unit-testing googletest googlemock


    【解决方案1】:

    您可以使用SaveArg<N> 操作来保存调用Listener::created(Obj&) 的参数的值,以便您可以将其值与maker.make() 之后返回的值进行比较。

    这将要求您为类Obj 提供相等运算符,即bool operator==(const Obj&, const Obj&)

    您的测试可能如下所示:

    class ListenerMock : public Listener
    {
    public:
        MOCK_METHOD1(created, void(Obj&));
    };
    
    TEST(MakerTest, make_registersObject)
    {
        ListenerMock lis;
        Maker maker;
        maker.register(lis);
    
        Obj createdArg;
        EXPECT_CALL(lis, created(_))
            .Times(1)
            .WillOnce(SaveArg<0>(&createdArg));
    
        Obj& o = maker.make();
    
        ASSERT_EQ(createdArg, o);
    }
    

    【讨论】:

      【解决方案2】:

      我认为答案是“这不是 google mocks 的用途。”

      它似乎是为“基于交互的测试”而不是“基于状态的测试”而设计的,正如 here 解释的那样:

      使用 Google Mock,您可以轻松地在 C++ 中创建模拟。人们可能会想在任何地方使用它们。有时它们工作得很好,有时你可能会发现它们使用起来很痛苦。那么,后一种情况有什么问题呢?

      当您在不使用模拟的情况下编写测试时,您可以运行代码并断言它返回正确的值或系统处于预期状态。这有时被称为“基于状态的测试”。

      Mocks 非常适合一些所谓的“基于交互”的测试:模拟对象不是在最后检查系统状态,而是验证它们是否以正确的方式调用并在出现错误时立即报告错误,从而为您提供触发错误的确切上下文的句柄。这通常比基于状态的测试更有效、更经济。

      如果您正在进行基于状态的测试并使用测试替身来模拟真实对象,那么您最好使用假的。在这种情况下使用模拟会导致痛苦,因为模拟不是执行复杂操作的强项。如果您遇到这种情况并认为模拟很糟糕,那么您只是没有使用正确的工具来解决您的问题。或者,您可能正在尝试解决错误的问题。 :-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-23
        • 1970-01-01
        • 1970-01-01
        • 2021-05-10
        • 2016-12-16
        • 2017-11-11
        • 2021-07-01
        • 2011-08-23
        相关资源
        最近更新 更多