【问题标题】:How to unit test my-sql database routes in express如何在 express 中对 mysql 数据库路由进行单元测试
【发布时间】:2019-08-24 08:41:48
【问题描述】:

我正在尝试对我的 nodejs rest api 进行单元测试,但由于事实上我几乎所有的路由都是对我的 my-sql 数据库的调用,我发现它非常困难。我一直在考虑可能嘲笑或存根我的数据库,但收效甚微(尝试过使用 Sinon)。我绝对不想在测试中对数据库进行真正的调用,所以我觉得存根/模拟是我唯一的选择,因为我在 npm my-sql 文档中没有看到任何关于设置测试 my-sql 数据库的文档.

我的数据库在一个单独的 server.js 文件中:

const mysql = require('mysql')

function getConnection() {
    return pool
}

module.exports = {
    connection: getConnection
}

const pool = mysql.createPool({
    connectionLimit: 10,
    host: 'localhost',
    user: 'root',
    password: '',
    database: '',
    port: 3306,
    multipleStatements: true,
})

我的主 app.js 文件处理所有路由:

const authentication = require('./routes/authentication.js')
const classes = require('./routes/class.js')
const cloudAnchors = require('./routes/cloudAnchors.js')
const assignments = require('./routes/assignments.js')
const assignmentSubmission = require('./routes/assignmentSubmission.js')
const models = require('./routes/models.js')
const webAppAuth = require('./routes/webAppAuth.js')

app.use(authentication)
app.use(classes)
app.use(cloudAnchors)
app.use(assignments)
app.use(assignmentSubmission)
app.use(models)
app.use(webAppAuth)

app.get("/", (req, res) => {
    console.log("Responding to root route")
    res.send("This is the root route...")
})

const PORT = process.env.PORT || 3003
app.listen(PORT, () => {
    console.log("Server is up and running...")
})

如果我们以 authentivation.js 为例,它包含如下路由,并将路由导出到 app.js 中使用:

router.post('/registerTeacher', (req, res) => {
    console.log("Trying to register a new teacher...")

    const email = req.body.email
    const type = req.body.type
    const name = req.body.name
    const hashedPassword = passwordHash.generate(req.body.password)
    console.log(hashedPassword)

    const queryString = "INSERT INTO users (name, email, password, type) VALUES (?, ?, ?, ?); INSERT INTO teacher (userId) VALUES (last_insert_id());"
    server.connection().query(queryString, [name, email, hashedPassword, type], (err, results, fields) => {
      if (err) {
        console.log("Failed to insert new student: " + err)
        res.send({
          "code":500,
          "success":"registration failed"
            });
        return
      }
      res.send({
        "code":200,
        "success":"registration sucessfull",
          });
    })
})

module.exports = router

我想知道如何最好地处理数据库以便能够单独测试路线。我很高兴调用路由,从模拟/存根数据库返回虚拟响应并检查它,但我只是在努力弄清楚如何实现它。似乎有更多关于存根/模拟猫鼬数据库的信息,但我没有发现任何有用的内容。

任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 创建一个mini-MySQL实例作为测试用户可行吗?或者将 mysql 作为 docker 容器运行并将测试数据放在那里?看起来存根会消除测试应用程序的很多用处。
  • @danblack 昨晚看,我遇到了这段代码process.env.NODE_ENV = 'test' 我目前正在本地运行我的应用程序,您认为将我的数据库的当前模式导出到测试中是否可以选择数据库然后在测试ENV中指向测试数据库?我仍然需要弄清楚如何去做,但你认为这是否足够测试?
  • 您的电话足够了。不过听起来是个不错的计划。

标签: mysql node.js unit-testing express mocking


【解决方案1】:

我面临同样的问题,我认为最好的解决方案是进行集成测试。 基本上,这里没有要测试的逻辑(否则您只需将逻辑放在路由器之外并对该特定功能进行单元测试),因此重点是测试路由器返回的数据是您实际期望的数据。

如何做到这一点?使用集成测试 (IT)。

根据我的知识和经验,我用我的数据库(在我的例子中是 MySql)的图像创建了一个 docker 容器,创建表,用一些自定义数据填充表。该数据是我期望作为路由器请求的输出的数据。

然后运行 ​​docker 容器,配置您的 IT 测试上下文,使其指向您的本地数据库,然后创建您自己的测试。它应该调用路由器并对结果做出断言。

希望将来对某人有用。

【讨论】:

    猜你喜欢
    • 2016-05-16
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多