如何在R中进行数据库连接/查询以进行单元测试

时间:2016-08-26 18:32:41

标签: r testthat

我正在使用testthat库在R项目中进行单元测试。我想测试依赖于数据库查询的代码,但不测试实际的查询本身。换句话说,我想模拟数据库连接和查询(让它们返回预定的数据集或命中测试数据库)。

我知道Ruby中有很多宝石,以及其他语言中的其他宝石,它们提供了这种功能。 R有什么类似的吗?或者我该如何完成它?

some_file.R:

sqlQuery <- function(some_query) {
        chnl <- odbcConnect(get.db.name())
        data <- sqlQuery(chnl, query)
}

来自测试文件:

test_that("test query", {
    dataset <- sqlQuery("SELECT * FROM some_database_table")
    #How to make this not actually hit the production database?
    expect_equal(nrow(dataset), 2)
} )

如果没有方便的包,testthat::with_mock()我最好打赌吗?

2 个答案:

答案 0 :(得分:1)

通过返回模拟结果来模拟sqlQuery函数:

library(testthat)

sqlQuery <- function(some_query) {
  chnl <- odbcConnect(get.db.name())
  data <- sqlQuery(chnl, query)
}

with_mock(sqlQuery = function(some_query) {
            if (grepl("SELECT * FROM some_database_table", some_query, fixed = TRUE))
              return(mtcars[1:2,])     # could also be loaded from file via "load" after using "save" once
            return(mtcars)  # default return value
          },
          {
            # Calls the mocked function now...
            dataset <- sqlQuery("SELECT * FROM some_database_table")
            expect_equal(nrow(dataset), 2)
          }
)

答案 1 :(得分:0)

如果您愿意相信SQLite与其他数据库说的是相同的SQL(大多数情况下都这样),则可以模拟一个本地SQLite数据库并对其进行调用。优点是您可以使用DB Browser for SQLite之类的内容轻松编辑数据库内容和测试结果。

将实现某种效果……

    # SQLite support & init
    library(DBI)
    library(RSQLite)

    putSQLiteHere <- "myRsqlite.sqlite" # could also be ":memory:"
    mySQLiteDB <- dbConnect(RSQLite::SQLite(),putSQLiteHere)

sqlQuery <- function(some_query) {
    data <- dbGetQuery(mySQLiteDB,some_query)
}

p.s。 Here's a more complete example of using SQLite with R ...