c++ - 如何使用 gmock 框架在 C++ 单元测试中模拟 fork 和 execlp 系统调用?

标签 c++ unit-testing fork googlemock execl

我有现有的 C++ 代码,它使用 fork() 系统调用创建子进程。子进程使用 execlp() 系统调用执行 linux 命令。现在我想使用具有 100% 代码覆盖率的 gmock 框架测试这段代码。我在谷歌上搜索了很多,但没有得到任何完整的证明解决方案。有人可以帮我解决这个问题吗?

这是我的 SUT:

int someclass :: os_fork()
{
  pid_t pid = fork();
  if (pid == -1) {
  cout<<"fork() failed with errno" <<errno <<endl;
  return false;
  }

  if (pid == 0 && (execlp("ls", "ls", nullptr) != 0))
  {
  cout<<"child process failed with errno"<<errno<<endl;
  return false;
  }
  int ppid = pid;
  return 0;
}

我想模拟 fork() 和 execlp() 系统调用。我怎么能那样做?

最佳答案

不可能按原样模拟全局函数。相反,您可以添加一个抽象层并将系统调用包装在一个接口(interface)中:

class OsInterface {
    virtual pid_t fork() = 0;
}

class OsInterfaceImpl : public OsInterface {
    virtual pid_t fork() override 
    {
        return ::fork();
    }
}

class OsInterfaceMock : public OsInterface {
    MOCK_METHOD0(fork, pid_t());
}

这允许您选择真正的系统调用或模拟 Dependency Injection .由于您没有提供任何代码,因此我无法帮助您。

通常,您将一个指针或对注入(inject)类的引用传递给应该使用它的类的构造函数,但很少有其他方法可以更好地适合您的项目。

额外的优势是此代码更开放-封闭:您可以轻松地(好吧,相对容易地)添加例如 Windows 实现而不更改现有代码 - 您只需提供另一个继承自的类OsInterface。您不必更改生产代码中对接口(interface)的任何调用,只需更改注入(inject)的类即可。

请注意,这不会在单元测试中运行任何额外的进程,但这是一个优势。您应该单独测试进程中运行的代码。

关于c++ - 如何使用 gmock 框架在 C++ 单元测试中模拟 fork 和 execlp 系统调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54147730/

相关文章:

C++ 函数指针作为默认模板参数

c++ - CUDA:访问冲突读取位置

c++ - 使用 c++11 编译时,Mingw g++ 无法识别 off_t

c++ - const void* 作为 C++ 中 MKL Blas 例程的复数

c - forks和pipes实现linux编译器

c++ - fork 子进程

c# - 在 Specflow 中,我可以将一个测试作为另一个步骤运行吗?

node.js - mocha 异步测试超时

unit-testing - 从命令行运行测试时如何强制 mstest 结果覆盖结果文件

c - 后台进程和文件输出的信号处理