如何在 C++ 中对 void 函数进行单元测试

时间:2021-05-12 08:56:24

标签: c++ unit-testing testing googletest void

我正在做一个业余项目,主要是为了学习 cpp 单元测试和数据库编程。但是,我对如何编写代码以进行适当的测试感到有些迷茫和困惑。我倾向于为我的 cpp 项目编写很多 void 函数。但是现在我不知道应该如何测试这些功能。我已经成功地测试了非空函数,因为它们返回的东西可以很容易地针对某个值进行测试。

我以不专业的方式做事?我应该尽可能避免使用 void 函数,以便我可以测试这些函数吗?或者我错过了什么?例如,我将如何测试此功能 -

database.cpp

#include "database.hpp"

#include <sqlite3.h>

#include <iostream>

#include "spdlog/sinks/basic_file_sink.h"

// Creating the logging object
auto logger = spdlog::basic_logger_mt("appnotex", "../data/appnotexlog");

void Database::createDb(const char *dbname) {
  // Creating the database file
  sqlite3 *datadb;
  int status = sqlite3_open(dbname, &datadb);

  //    checking for errors
  if (status == SQLITE_OK) {
    logger->info("------------ New Session ----------");
    logger->info("Connected to Database Successfully");
  } else {
    std::string errorMessage = sqlite3_errmsg(datadb);
    logger->info("Error: " + errorMessage);
  }

如果需要

  • 我正在使用 Google Test 框架
  • 我托管的整个项目代码 - here

更新

我已经尝试过这个方法,这种测试上述方法的方法正确吗?

databaseTest.cpp

TEST(DatabaseTest, createDbTest) {
  const char *dbfilename = "../data/test/data.db";
  const char *tbname = "DataTest";
  Database *db = new Database();

  std::ifstream dbfile("../data/test/data.db");
  bool ok = false;
  if (!dbfile.is_open())
    ok = false;
  else
    ok = true;

  EXPECT_TRUE(ok);
}

1 个答案:

答案 0 :(得分:2)

问题不在于返回 void 的函数。想想它如何发出错误信号,并确保所有情况(成功和失败)都经过测试,就这么简单。

但是,除了记录它之外,我根本看不到任何错误信号。根据经验,日志记录只能用于事后研究等。因此,如果日志记录完全失败,您的程序仍然可以正确运行。这意味着,内部没有任何东西依赖它,它也不是一个合适的错误处理/信号机制。

现在,基本上有三种方式来表示错误:

  1. 返回值。通常用于 C 代码,有时也用于 C++。使用 void 返回,这不是一个选项,这可能是您问题的来源。
  2. 例外。您可以 throw std::runtime_error("DB connect failed"); 并将处理它委托给调用代码。
  3. 副作用。您可以将连接状态存储在 Database 实例中。为完整起见,也可以使用全局 errno,但不可取。

无论如何,这三种方式都可以在单元测试中进行练习和验证。

相关问题