Как смоделировать системные вызовы fork и execlp в модульном тесте c ++ с использованием фреймворка gmock? - PullRequest
0 голосов
/ 11 января 2019

У меня есть код на C ++, который создает дочерний процесс с помощью системного вызова fork (). И дочерний процесс выполняет команду linux с помощью системного вызова execlp (). Теперь я хочу протестировать этот код, используя gmock framework со 100% покрытием кода. Я много гуглил, но я не получил никакого полного решения. Кто-нибудь может мне помочь с этим?

Это мой СУТ:

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 (). Как я мог это сделать?

1 Ответ

0 голосов
/ 11 января 2019

Нельзя имитировать глобальные функции такими, какие они есть. Вместо этого вы можете добавить слой абстракции и обернуть системные вызовы в интерфейсе:

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());
}

Это позволяет вам выбрать реальный системный вызов или макет с помощью Внедрение зависимости . Поскольку вы не предоставили код, я не могу вам с этим помочь.

Обычно вы передаете указатель или ссылку на внедренный класс в конструктор класса, который должен его использовать, но есть несколько других методов, которые могли бы лучше подойти вашему проекту.

Дополнительным преимуществом является то, что этот код является более открытым-закрытым : Вы можете легко (ну, относительно легко) добавить, например, реализацию Windows, не изменяя существующий код - вы просто предоставите другой класс, наследующий от OsInterface. Вам не нужно изменять какие-либо вызовы интерфейса в вашем производственном коде, просто измените внедренный класс.

Обратите внимание, что это не будет запускать никаких дополнительных процессов в модульных тестах, но это является преимуществом. Вы должны проверить код, запущенный в процессе отдельно.

...