Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编写检查定时行为的快速测试_C++_Googletest_Googlemock - Fatal编程技术网

C++ 编写检查定时行为的快速测试

C++ 编写检查定时行为的快速测试,c++,googletest,googlemock,C++,Googletest,Googlemock,我有以下课程(当然,对于这个例子,我会简化): 此类要求在任何写入之前调用init,然后您可以使用此类将写入文件。但是,在经过ms毫秒后,write停止写入文件并返回错误 我的问题是-如何为这种行为创建快速单元测试?任何足够小的值都将创建一个非确定性测试,该测试有时会由于机器上运行的其他进程而失败。但是,我希望测试尽可能快,并且不包括任何睡眠或类似的内容。我正在使用谷歌测试和谷歌模拟 首先,我必须从你的实际问题中转移一点注意力。请不要创建这样的接口。无论何时创建对象,其所有函数都必须可调用,直到

我有以下课程(当然,对于这个例子,我会简化):

此类要求在任何
写入
之前调用
init
,然后您可以使用此类将写入文件。但是,在经过
ms
毫秒后,
write
停止写入文件并返回错误


我的问题是-如何为这种行为创建快速单元测试?任何足够小的值都将创建一个非确定性测试,该测试有时会由于机器上运行的其他进程而失败。但是,我希望测试尽可能快,并且不包括任何
睡眠
或类似的内容。我正在使用谷歌测试和谷歌模拟

首先,我必须从你的实际问题中转移一点注意力。请不要创建这样的接口。无论何时创建对象,其所有函数都必须可调用,直到其生命周期结束。非正式的生存期约束,如“必须在write()之前调用init()”,或者更糟糕的是,“在析构函数之前始终调用close()”,不能由编译器检查,因此容易出错

因此,我认为,您不应该试图在测试中解决这个问题,而应该在测试代码的设计中解决这个问题。无论何时编写测试很困难,都可以肯定,您的接口是有缺陷的

我的建议是把时间和写作分开。创建一个计时器类,例如:

#include <memory>
#include <chrono>

template<typename T>
class Timer {
    private:
        std::chrono::milliseconds time_to_live;
        std::shared_ptr<T> timed_object;
    public:
        template<typename... Arg>
        Timer(std::chrono::milliseconds ttl, Arg... args):
          time_to_live{ttl},
          timed_object{std::make_shared<T>(args...)} {};

        std::weak_ptr<T> get() { return {timed_object}; };
        // ...
        // when the defined time is over, timed_object will be set to nullptr somehow.
};
#包括
#包括
模板
班级计时器{
私人:
std::chrono::毫秒时间\u到\u活动;
std::共享\u ptr定时\u对象;
公众:
模板
计时器(std::chrono::毫秒ttl,Arg…args):
生活的时间{ttl},
定时_对象{std::使_共享(args…}{};
std::weak_ptr get(){return{timed_object};};
// ...
//定义的时间结束后,timed_对象将以某种方式设置为nullptr。
};
像这样使用它:

#include <chrono>
#include <iostream>
#include <fstream>

int main(int, char**)
{
    using namespace std::literals::chrono_literals;

    auto timed_ostream = Timer<std::ofstream>{42ms, "filename"};
    if( !timed_ostream.get().expired() ) {
       // os is a shared_ptr. That guarantees, that the ostream will not
       // be closed while you are still writing.
       auto os = timed_ostream.get().lock();
       (*os) << "whatever";
    } // now os will be destroyed. The ofstream might be destroyed
      // as well now, when the 42ms are over.
} // OK, here we destroy the timer and therefore the ofstream,
  // if it is still alive.
#包括
#包括
#包括
int main(int,char**)
{
使用名称空间std::literals::chrono_literals;
自动定时\u ostream=计时器{42ms,“文件名”};
如果(!timed_ostream.get().expired()){
//os是一个共享的ptr。这保证了ostream不会
//当你还在写作时,请关闭。
自动操作系统=timed_ostream.get().lock();

(*os)首先,我必须稍微偏离你的实际问题。请不要创建这样的接口。无论何时创建对象,其所有函数都必须可调用,直到其生命周期结束。非正式的生命周期约束,如“init()必须在write()之前调用”,甚至更糟糕的是“always call close())之前,编译器无法检查析构函数,因此容易出错

因此,我不认为你应该在测试中解决这个问题,而是在被测试代码的设计中。每当编写测试很困难时,你的接口肯定是有缺陷的

我的建议是将计时和写作分开。创建一个计时器类,例如:

#include <memory>
#include <chrono>

template<typename T>
class Timer {
    private:
        std::chrono::milliseconds time_to_live;
        std::shared_ptr<T> timed_object;
    public:
        template<typename... Arg>
        Timer(std::chrono::milliseconds ttl, Arg... args):
          time_to_live{ttl},
          timed_object{std::make_shared<T>(args...)} {};

        std::weak_ptr<T> get() { return {timed_object}; };
        // ...
        // when the defined time is over, timed_object will be set to nullptr somehow.
};
#包括
#包括
模板
班级计时器{
私人:
std::chrono::毫秒时间\u到\u活动;
std::共享\u ptr定时\u对象;
公众:
模板
计时器(std::chrono::毫秒ttl,Arg…args):
生活的时间{ttl},
定时_对象{std::使_共享(args…}{};
std::weak_ptr get(){return{timed_object};};
// ...
//定义的时间结束后,timed_对象将以某种方式设置为nullptr。
};
像这样使用它:

#include <chrono>
#include <iostream>
#include <fstream>

int main(int, char**)
{
    using namespace std::literals::chrono_literals;

    auto timed_ostream = Timer<std::ofstream>{42ms, "filename"};
    if( !timed_ostream.get().expired() ) {
       // os is a shared_ptr. That guarantees, that the ostream will not
       // be closed while you are still writing.
       auto os = timed_ostream.get().lock();
       (*os) << "whatever";
    } // now os will be destroyed. The ofstream might be destroyed
      // as well now, when the 42ms are over.
} // OK, here we destroy the timer and therefore the ofstream,
  // if it is still alive.
#包括
#包括
#包括
int main(int,char**)
{
使用名称空间std::literals::chrono_literals;
自动定时\u ostream=计时器{42ms,“文件名”};
如果(!timed_ostream.get().expired()){
//os是一个共享的ptr。这保证了ostream不会
//当你还在写作时,请关闭。
自动操作系统=timed_ostream.get().lock();
(*操作系统)