开玩笑地测试猫鼬模型实例化

埃费莫拉夫

我正在尝试测试使用express和mongoose构建的REST API,我正在对http调用使用jest和supertest;我对使用javascript测试还是比较陌生。

在测试创建网址时,我不会确保仅使用req.body对象调用了实例化,但是在阅读了许多关于模拟对象与存根之间的差异以及一些Jest的区别之后,我不确定如何做到这一点我最后一次尝试的文档如下所示:

test('Should instantiate the model using req.body', done => {

  const postMock = jest.fn();

  const testPost = {
    name: 'Test post',
    content: 'Hello'
  };

  postMock.bind(Post); // <- Post is my model

  // I mock the save function so it doesn't use the db at all
  Post.prototype.save = jest.fn(cb => cb(null, testPost));

  // Supertest call
  request(app).post('/posts/')
  .send(testPost)
  .then(() => {
    expect(postMock.mock.calls[0][0]).toEqual(testPost);
    done();
  })
  .catch(err => {throw err});

});

我也想知道如何在promise拒绝上手动失败测试,​​所以它不会抛出 Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

弗朗西斯科·马特奥(Francisco Mateo)

就目前而言,您将执行更多的集成测试,而不是隔离路由处理程序功能本身并对其进行测试。

首先,我将处理程序拆分为/posts/自己的文件(假设您尚未执行此操作):

controllers/post-controller.js

const Post = require('./path/to/models/post')

exports.store = async (req, res) => {
  const post = await new Post(req.body).save()
  res.json({ data: post }
}

接下来,只需在定义路线的任何地方使用处理程序:

const express = require('express')
const app = express()
const postController = require('./path/to/controllers/post-controller')

app.post('/posts', postController.store)

有了这个抽象,我们现在可以隔离我们的代码postController.store并测试它是否适用req.body现在,由于我们需要模拟猫鼬以避免访问实际的数据库,因此您可以Post像这样创建一个模拟对象(使用您已有的代码):

path/to/models/__mocks__/post.js

const post = require('../post')

const mockedPost = jest.fn()
mockedPost.bind(Post)

const testPost = {
  name: 'Test post',
  content: 'Hello'
}


Post.prototype.save = jest.fn(cb => {
  if (typeof cb === 'function') {
    if (process.env.FORCE_FAIL === 'true') {
      process.nextTick(cb(new Error(), null))
    } else {
      process.nextTick(cb(null, testPost))
    }
  } else {
    return new Promise((resolve, reject) => {
      if (process.env.FORCE_FAIL === 'true') {
        reject(new Error())
      } else {
        resolve(testPost)
      }
    })
  }
})

module.exports = mockedPost

请注意检查process.env.FORCE_FAIL是否由于任何原因使它失败。

现在,我们准备使用req.body作品进行测试

post-controller.test.js

// Loads anything contained in `models/__mocks__` folder
jest.mock('../location/to/models')

const postController = require('../location/to/controllers/post-controller')

describe('controllers.Post', () => {
  /**
   * Mocked Express Request object.
   */
  let req

  /**
   * Mocked Express Response object.
   */
  let res

  beforeEach(() => {
    req = {
      body: {}
    }
    res = {
      data: null,
      json(payload) {
        this.data = JSON.stringify(payload)
      }
    }
  })

  describe('.store()', () => {
    test('should create a new post', async () => {
      req.body = { ... }
      await postController(req, res)
      expect(res.data).toBeDefined()

      ...
    })

    test('fails creating a post', () => {
      process.env.FORCE_FAIL = true
      req.body = { ... }

      try {
        await postController.store(req, res)
      } catch (error) {
        expect(res.data).not.toBeDefined()

        ...
      }
    })

  })
})

该代码未经测试,但希望对您的测试有所帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章