【问题标题】:How to write a general function callback test class?如何编写一个通用的函数回调测试类?
【发布时间】:2014-06-12 14:39:02
【问题描述】:

我有几个类,每个类都存储并调用回调函数。回调函数的签名有不同的参数和返回类型,但它们都只接受一个参数。

为了验证这些类是否应该调用它们的回调,我正在尝试编写一个通用测试类,它 (1) 提供一个带有一个参数的回调函数,(2) 让用户查询该函数是否已经调用,并且 (3) 让用户检查传递给该函数的参数。到目前为止,我有这样的事情:

template<class ReturnType, class ParameterType> class Callable
{
    public:
        Callable() : m_called(false), m_param() {}
        ReturnType operator()(ParameterType param)
        {
            m_called = true;
            m_param = param;
            return Returntype();
        }
        bool Called() { return m_called; }
        ParameterType Param() { return m_param; }

    private:
        bool m_called;
        ParameterType m_param;
};

这是一个可以使用类 Callable 进行测试的类:

#include <boost/function.hpp>

class ToBeTested
{
    ToBeTested(boost::function<bool (int)> callback) : m_callback(callback) {};
    boost::function<bool (int)> m_callback;

    //  (methods which should cause the callback to be called here)
};

这是一些测试代码:

#include <boost/bind.hpp>

int main(int, char**)
{
    Callable<bool, int> callable;
    ToBeTested tbt(boost::bind(&Callable<bool, int>::operator());

    //  (tell tbt it should call its callback here)

    if (callable.Called()
    {
        if (EXPECTED_VALUE == callable.Param();
        return 0;
    }

    return -1;
}

这给了我 (1) 和 (2),但是当回调通过引用获取其参数时 (3) 存在问题:Callable::m_param 是引用类型,因此不能默认初始化。我可以通过让 Callable::operator() 通过引用获取其参数来解决这个问题,如下所示:

    ReturnType operator()(ParameterType & param)

...但是当回调函数按值获取其参数时,我不能使用类 Callable。

有没有办法让我的测试类工作,不管回调函数是通过引用获取它的参数,还是我需要编写两个几乎相同的测试类?

【问题讨论】:

    标签: c++ unit-testing templates


    【解决方案1】:

    您可以尝试这样的方法,其中引用实际上存储为指针:

    template<typename T>
    struct ref_to_ptr
    {
        typedef T type;
    
        static T wrap(T x) { return x; }
        static T unwrap(T x) { return x; }
    };
    
    template<typename T>
    struct ref_to_ptr<T&>
    {
        typedef T* type;
    
        static T* wrap(T& x) { return &x; }
        static T& unwrap(T* x) { return *x; }
    };
    
    template<class ReturnType, class ParameterType> class Callable
    {
        public:
            Callable() : m_called(false), m_param() {}
            ReturnType operator()(ParameterType param)
            {
                m_called = true;
                m_param = ref_to_ptr<ParameterType>::wrap(param);
                return Returntype();
            }
            bool Called() { return m_called; }
            ParameterType Param() { return ref_to_ptr<ParameterType>::unwrap(m_param); }
    
        private:
            bool m_called;
            typename ref_to_ptr<ParameterType>::type m_param;
    };
    

    【讨论】:

    • 谢谢 - 我和我的同事刚刚学到了一些我们不知道模板可以做到的事情。 :-)
    猜你喜欢
    • 2021-09-25
    • 2021-08-10
    • 2021-12-22
    • 2019-10-01
    • 2020-07-17
    • 2014-09-09
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多