如何使用googlemock模拟可变参数函数

11

这不是一个问题,而是一段知识分享。

根据GoogleMock的FAQ,无法模拟可变参数函数,因为不知道函数将传递多少个参数。

虽然如此,在大多数情况下,我们都知道系统测试下调用可变参数函数的变量数量或者如何将可变参数转换为一个非可变参数。
我的一位同事(我不知道他是否在Stackoverflow上活跃)提出了一个可行的解决方案,如以下示例所示(使用C类型接口的模拟):

    class MockInterface
    {
        public:
            MockInterface() {}
            ~MockInterface() {}
            MOCK_METHOD4( variadicfunction, void( const std:: string name, AN_ENUM mode,
                 const std::string func_name, const std::string message ) );
    };

    boost::shard_ptr<MockInterface> mock_interface;

    extern "C"
    {
        void variadicfunction( const char *name, AN_ENUM mode,
            const char *func_name, const char *format, ... )
        {
            std::string non_variadic("");

            if (format != NULL )
            {
                va_list args;
                va_start( args, format );

                // Get length of format including arguments
                int nr = vsnprintf( NULL, 0, format, args );

                char buffer[nr];
                vsnprintf( buffer, nr+1, format, args );

                non_variadic = std::string( buffer );

                va_end( args );
            }
            
            mock_interface->variadicfunction( name, mode, func_name, non_variadic );
        }
    }

希望这对你有所帮助。


真是个聪明的技巧!但是,我认为你有一个缓冲区溢出(应该使用索引号+1来声明缓冲区)。感谢分享。 - Bert Regelink
我认为即使不进行到non_variadic的转换,这也是可以完成的。在此处可以查看完整的示例:https://dev59.com/p3kPtIcB2Jgan1znl3qj#73613788 - Ari
@Ari:你在评论一个非常古老的“问题”(更像是一份配方);-)。现在可以不进行转换就能完成。但是在我写这篇文章的时候(2014年),这是不可能的。Googlemock已经发展了很多(例如,你想要模拟的方法的10个参数限制也消失了)。 - Nemelis
@Nemelis 同意。抱歉发了个随意的评论,我没有注意到日期!只是想放一个链接以防有人想要看一个更近期的例子。没有贬低您在这里的回答的意图。 - Ari
1个回答

3

我不能评论上一个答案,但是它有两个错误:

  1. 缓冲区太小了(@Bert已经提到过)
  2. 在虚拟的 vsnprintf()(为了获取所需的 buffer-size),args 指向最后一个可变参数后面,因此在真正的 vsnprintf() 之前必须将其重置。

这是已更正的部分:

if (format != NULL )
{
    va_list args;

    va_start( args, format );
    // Get length of format including arguments
    int nr = vsnprintf( NULL, 0, format, args );
    va_end( args );

    char buffer[nr+1];
    va_start( args, format );
    vsnprintf( buffer, nr+1, format, args );
    va_end( args );

    non_variadic = std::string( buffer );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接