c++ - 如何创建用于使用 gtest 进行测试的 sqlite3_value

标签 c++ sqlite googletest

我正在为 sqlite3 编写一个包装类,这只是 4 的乐趣,并且正在学习 c++11 和 gtest。我正在用 gtest 测试我的包装器。在一个特定的测试用例中,我需要一个 sqlite3_value 对象来比较我的函数结果。我不知道如何从头开始创建 sqlite3_value 对象。我在网上搜索并找到了这个解决方案:

sqlite3 *tmpDB;
sqlite3_open_v2(":memory", &tmpDB, SQLITE_OPEN_READWRITE, 0);
sqlite3_stmt *tmpStmt = nullptr;

sqlite3_prepare_v2(tmpDB, "SELECT ?;", 9, &tmpStmt, nullptr);
sqlite3_bind_text(tmpStmt, 0, "paul", 4, SQLITE_TRANSIENT);
int res = sqlite3_step(tmpStmt);
std::string s(reinterpret_cast<const char*>(sqlite3_value_text(sqlite3_column_value(tmpStmt, 0)))); /*Here throws the exception below*/
sqlite3_finalize(tmpStmt);

在调用 sqlite3_finalize() 之前构造字符串会抛出以下异常:

在测试主体中抛出描述为“basic_string::_M_construct null not valid”的 C++ 异常

我尝试了堆栈溢出的解决方案: Stack Overflow std::basic_string solution 但我有同样的异常(exception)。

我不确定是否可以从头开始构建 sqlite3_value。我尝试“构建”sqlite3_value 的方式是否正确?

也许我必须考虑使用其他类型作为 std::string。我读到一些原因,比如 std::string do not support text witch is not plain ACSII。是吗?

有什么建议吗?

最佳答案

首先要注意的是:您引用的异常意味着您将 nullptr 传递给了 std::string 构造函数。这是被禁止的。您传递空指针的原因是您在不代表 STRING 值的值上使用了 sqlite3_value_text。这又是查询失败造成的。

目前CL对答案的修改有很多好的方面。让我们从最重要的建议开始:

Also, you must check the return values of all functions for errors.

您说您正在使用 Google Test,那么让我们使用 EXPECT_EQ 语句来查明这些函数是否确实返回了您期望的值。这是一个完整的最小示例,添加了错误检查:

#include <sqlite3.h>
#include <string>
#include <gtest/gtest.h>

int main(void)
{
  sqlite3 *tmpDB;
  EXPECT_EQ(SQLITE_OK, sqlite3_open_v2(":memory", &tmpDB, SQLITE_OPEN_READWRITE, 0));
  sqlite3_stmt *tmpStmt = nullptr;

  EXPECT_EQ(SQLITE_OK, sqlite3_prepare_v2(tmpDB, "SELECT ?;", 9, &tmpStmt, nullptr));
  EXPECT_EQ(SQLITE_OK, sqlite3_bind_text(tmpStmt, 0, "paul", 4, SQLITE_TRANSIENT));
  int res = sqlite3_step(tmpStmt);
  EXPECT_EQ(SQLITE_ROW, res);
  std::string s(reinterpret_cast<const char*>(sqlite3_value_text(sqlite3_column_value(tmpStmt, 0))));
  EXPECT_EQ(SQLITE_OK, sqlite3_finalize(tmpStmt));
}

这样会输出大量的期望失败。哎呀!第一个预期失败是 sqlite_open 返回 14 (SQLITE_CANTOPEN)。仔细看CL给出的答案就可以找到原因,其实仔细看第一句就够了。

修复后,sqlite3_bind_text 上的 EXPECT_EQ 失败,错误代码为 25 (SQLITE_RANGE)。阅读 sqlite3_bind_text 的文档,特别是描述第二个参数的段落的前两句,以找出此调用中的错误。

同样,在修复此问题后,我不再遇到异常或任何预期失败。

关于c++ - 如何创建用于使用 gtest 进行测试的 sqlite3_value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34652411/

相关文章:

c++ - 为什么不能在实例化派生类指针的同时实例化对基类的引用?

c++ - 在 C++ 应用程序中嵌入 Ruby 解释器

c# - 使用单声道从 C++ 传递 C# 枚举

c++ - 返回*这个;删除指针

c++ - 是否可以在 googletest 的 Predicate Formatter 中使用 ASSERT_NEAR

c++ - GTest-如何通过SetUp方法为多次使用准备数据?

c++ Google测试运行两次

javascript - jQuery 以错误的顺序执行代码部分

ios - 如何在 swift 3 中使用现有的 SQLite? (FMDB)

mongodb - 为什么在使用 Homebrew 安装 MongoDB 时 sqlite 是 MongoDB 依赖项