如何正确地对 Joi Schemas 验证进行单元测试?

How does one properly to unit test Joi Schemas validation?

我创建了一个在我的路线中调用的 Joi 验证模式。但是,当我 运行 代码覆盖时,该文件未被覆盖。所以,我正在尝试为它编写一个测试。

Validator.js

    const Joi = require('joi');
    module.exports = {
    validateExternalId: (schema, name) => {
    return (req, res, next) => {
      const result = Joi.validate({ param: req.params[name] }, schema);
      if (result.error) {
        return res.status(400).send(result.error.details[0].message);
      }
      next();
    };
  },
schemas: {
    idSchema: Joi.object().keys({
      param: Joi.string().regex(/^[a-zA-Z0-9]{20}$/).required()
    })
  }
};

Validator.test.js

const { validateExternalId, schemas } = require('../../src/helpers/validation');
const app = require('../../src/router')

const mockResponse = () => {
  const res = {};
  res.status = jest.fn().mockReturnValue(res);
  res.json = jest.fn().mockReturnValue(res);
  return res;
};

describe('Testing validateExternalId schema', () => {
  it('It can validate the external Id Regex length', done => {
    const req = {
      params: [
        {
          extClientId: 'abcdefghij0123456789'
        }
      ]
    };

  app.use('/token/:extClientId', validateExternalId(schemas.idSchema, 'extClientId');
    // expect().toHaveBeenCalled();
  });
});

请放轻松...这是我测试此 Joi 验证器的尝试。我试过了,但我的预期没有用,所以我暂时把它注释掉了。任何指针将不胜感激。谢谢

单元测试解决方案如下:

validator.js:

const Joi = require('joi');

module.exports = {
  validateExternalId: (schema, name) => {
    return (req, res, next) => {
      const result = Joi.validate({ param: req.params[name] }, schema);
      if (result.error) {
        return res.status(400).send(result.error.details[0].message);
      }
      next();
    };
  },
  schemas: {
    idSchema: Joi.object().keys({
      param: Joi.string()
        .regex(/^[a-zA-Z0-9]{20}$/)
        .required(),
    }),
  },
};

validator.test.js:

const { validateExternalId, schemas } = require('./validator');
const Joi = require('joi');

describe('60730701', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('should send error', () => {
    const validationResults = { error: { details: [{ message: 'validation error' }] } };
    const validateSpy = jest.spyOn(Joi, 'validate').mockReturnValueOnce(validationResults);
    const mReq = { params: { extClientId: '123' } };
    const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
    validateExternalId(schemas.idSchema, 'extClientId')(mReq, mRes);
    expect(validateSpy).toBeCalledWith({ param: '123' }, schemas.idSchema);
    expect(mRes.status).toBeCalledWith(400);
    expect(mRes.send).toBeCalledWith('validation error');
  });

  it('should pass the validation and call api', () => {
    const validationResults = { error: undefined };
    const validateSpy = jest.spyOn(Joi, 'validate').mockReturnValueOnce(validationResults);
    const mReq = { params: { extClientId: '123' } };
    const mRes = {};
    const mNext = jest.fn();
    validateExternalId(schemas.idSchema, 'extClientId')(mReq, mRes, mNext);
    expect(validateSpy).toBeCalledWith({ param: '123' }, schemas.idSchema);
    expect(mNext).toBeCalled();
  });
});

100% 覆盖率的单元测试结果:

 PASS  Whosebug/60730701/validator.test.js (9.96s)
  60730701
    ✓ should send error (6ms)
    ✓ should pass the validation and call api (2ms)

--------------|---------|----------|---------|---------|-------------------
File          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
--------------|---------|----------|---------|---------|-------------------
All files     |     100 |      100 |     100 |     100 |                   
 validator.js |     100 |      100 |     100 |     100 |                   
--------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        11.647s, estimated 15s

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/Whosebug/60730701