在node.js中为链式功能编写笑话测试

时间:2018-09-07 12:04:14

标签: javascript node.js unit-testing express jestjs

我有一个要用玩笑来测试的函数,该函数基本上会进行一些令牌验证,并需要3个参数

这是我要测试的功能的代码:

const verifyToken = (req, res, next) => {
    // check header or url parameters or post parameters for token
    var token = req.headers['x-access-token']

    if (!token) return res.status(403).send({ auth: false, message: 'No token provided.' })

    // verifies secret and checks expire date
    jwt.verify(token, config.secret, (err, decoded) => {
        if (err) return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' })

        //put user inside req.user to use the user in other routes
        User.findById(decoded.id, (err, user) => {
            if (err) {
                return res.status(500).json({
                    message: err
                })
            } else if (!user) {
                return res.status(404).json({
                    message: 'No user found'
                })
            } else {
                req.user = user
            }
            next()
        })
    })
}

因此,我正在编写第一个测试,该测试测试是否在请求中未提供令牌,即发送带有消息的403。以下是测试。

const verifyToken = require('../../config/token')

describe('veryfiy token tests', () => {
    it('Should give 403 status when no token is present', () => {
        let mockReq = {
            headers: {}
        }
        var mockRes = {
            status: code => code
            send: message => message
        }

        let nextCalled = false

        let next = () => {
            nextCalled = true
        }

        expect(verifyToken(mockReq, mockRes, next)).toBe(403)
    })
})

现在测试通过并出现错误: TypeError:res.status(...)。send不是函数

当我从代码中的res.status中删除.send()时,测试通过。

我一直试图找出如何在res对象上模拟status()和send()。但尚未找到解决方案。

Tnx

2 个答案:

答案 0 :(得分:1)

我认为问题在于res.status()的结果没有名为send()的函数。

尝试使用此:

  var mockRes = {
    status: code => ({
      send: message => ({code, message})
    }),
  };

您应该可以通过以下方式进行测试:

  var result = verifyToken(mockReq, mockRes, next);
  expect(result.code).toBeDefined();
  expect(result.code).toBe(403);

PS:尚未测试代码:)

答案 1 :(得分:0)

您可以进行链接的模拟类和测试,无论是否执行功能。

这是一个例子。

import SceneKit.ModelIO

private let device = MTLCreateSystemDefaultDevice()!

//MARK: thumbnail
/// Create a thumbnail image of the asset with the specified URL at the specified
/// animation time. Supports loading of .scn, .usd, .usdz, .obj, and .abc files,
/// and other formats supported by ModelIO.
/// - Parameters:
///     - url: The file URL of the asset.
///     - size: The size (in points) at which to render the asset.
///     - time: The animation time to which the asset should be advanced before snapshotting.

func thumbnail(for url: URL, size: CGSize, time: TimeInterval = 0) -> UIImage? {
    let renderer = SCNRenderer(device: device, options: [:])
    renderer.autoenablesDefaultLighting = true

    if (url.pathExtension == "scn") {
        let scene = try? SCNScene(url: url, options: nil)
        renderer.scene = scene
    } else {
        let asset = MDLAsset(url: url)
        let scene = SCNScene(mdlAsset: asset)
        renderer.scene = scene
    }

    let image = renderer.snapshot(atTime: time, with: size, antialiasingMode: .multisampling4X)
    return image
}

,现在使用此模拟类进行测试。并检查给定功能是否已执行给定结果。 像

  class MockResponse {
    constructor() {
    this.res = {};
     }
     status = jest
     .fn()
     .mockReturnThis()
     .mockImplementationOnce((code) => {
       this.res.code = code;
      return this;
     });
    send = jest
    .fn()
    .mockReturnThis()
    .mockImplementationOnce((message) => {
      this.res.message = message;
      return this;
    });
    }