2015-02-27 7 views
4

Как я могу проверить результаты проверки, выполненные с помощью экспресс-валидатора?Проверка модульного тестирования с помощью экспресс-валидатора

Я пробовал создать объект-образец, но получаю ошибку: TypeError: Object #<Object> has no method 'checkBody'. Я могу вручную проверить, что валидация работает в приложении.

Вот что я пробовал:

describe('couponModel', function() { 
    it('returns errors when necessary fields are empty', function(done){ 
     var testBody = { 
      merchant : '', 
      startDate : '', 
      endDate : '' 
     }; 
     var request = { 
      body : testBody 
     }; 
     var errors = Model.validateCouponForm(request); 
     errors.should.not.be.empty; 
     done(); 
    }); 
}); 

Я понимаю, что метод checkBody добавляется к объекту запроса, когда я app.use(expressValidator()) в моем экспресс-приложение, но я только тестирование, что валидация работающий в этом модульном тесте. У меня нет экземпляра экспресс-приложения, и метод проверки, который я тестирую, не вызывается непосредственно из него в любом случае, поскольку он вызывается только через почтовый маршрут, который я не хочу вызывать единичный тест, поскольку он включает операцию базы данных.

ответ

1

Я сталкивался с таким же вопросом, и я должен был создать методы использования этого:

var validRequest = { 
    // Default validations used 
    checkBody: function() { return this; }, 
    checkQuery: function() { return this; }, 
    notEmpty: function() { return this; }, 

    // Custom validations used 
    isArray: function() { return this; }, 
    gte: function() { return this; }, 

    // Validation errors 
    validationErrors: function() { return false; } 
}; 

function getValidInputRequest(request) { 
    Object.assign(request, validRequest); 
    return request; 
} 

Таким образом, в вашем коде, вы должны вызвать getValidInputRequest помощника:

describe('couponModel', function() { 
    it('returns errors when necessary fields are empty', function(done){ 
     var testBody = { 
      merchant : '', 
      startDate : '', 
      endDate : '' 
     }; 
     var request = { 
      body : testBody 
     }; 

     request = getValidInputRequest(request); // <-- Update the request 

     var errors = Model.validateCouponForm(request); 
     errors.should.not.be.empty; 
     done(); 
    }); 
}); 

Теперь, request объект имеет свойство body и все методы, необходимые для экспресс-валидации.

Если вы хотите, чтобы проверить случаи, что валидатор не работает, вы должны использовать что-то вроде этого:

function getInvalidInputRequest(request, errorParams) { 
    // Get de default valid request 
    Object.assign(request, validRequest); 

    // Override the validationErrors function with desired errors 
    request.validationErrors = function() { 
     var errors = []; 
     errorParams.forEach(function(error){ 
      errors.push({msg: 'the parameter "'+ error +'" is mandatory'}) 
     }); 
     return errors; 
    }; 
    return request; 
} 

И обновить запрос вы должны сделать:

request = getInvalidInputRequest(request, ['mandatory_param_1', 'mandatory_param_2']); 
1

Вот решение для нового экспресс-валидатора api (v4):

tl; dr: Вы можете использовать это функция:

exports.testExpressValidatorMiddleware = async (req, res, middlewares) => { 
    await Promise.all(middlewares.map(async (middleware) => { 
    await middleware(req, res,() => undefined); 
    })); 
}; 

Это можно назвать как это:

const { validationResult } = require('express-validator/check'); 

await testExpressValidatorMiddleware(req, res, expressValidatorMiddlewareArray); 
const result = validationResult(req); 
expect(result.... 

Эти решения Предположим, у вас есть асинхронная/Await синтаксис доступен. Вы можете использовать библиотеку node-mocks-http для создания объектов и res.

Пояснение:

Каждый элемент в массиве экспресс-валидатора наносится на маршрут в качестве промежуточного программного обеспечения. Скажем, это ваш массив:

[ 
    check('addresses.*.street').exists(), 
    check('addresses.*.postalCode').isPostalCode(), 
] 

Каждая проверка будет загружена как промежуточное программное обеспечение.

Для тестирования промежуточного программного обеспечения нам необходимо реализовать функцию, которая действует аналогично тому, как express реализует промежуточное программное обеспечение.

Быстрое промежуточное программное обеспечение всегда принимает три параметра, объекты запроса и ответа и следующую функцию, которую он должен вызывать (next по соглашению). Зачем нам нужен next? Для сценариев, где мы хотим, чтобы наше промежуточное программное обеспечение что-то делало до и после функции продолжения, например.

const loggerMiddleware = (req, res, next) => { 
    console.log('req body is ' + req.body); 
    next(); 
    console.log('res status is ' + res.status); 
}; 

Но экспресс-валидатор не делает этого, он просто вызывает next() когда каждый из его валидаторов закончена. По этой причине нам не нужно беспокоиться об next().

Вместо этого мы можем просто запустить каждый из наших в свою очередь, промежуточное программное и передать пустую функцию next, чтобы избежать TypeError:

middlewares.map((middleware) => { 
    middleware(req, res,() => undefined); 
}); 

Но это не будет работать, потому что экспресс-валидатор промежуточного возвращает обещания и мы должны ждать их, чтобы решить ...

middlewares.map(async (middleware) => { 
    await middleware(req, res,() => undefined); 
}); 

И мы не хотим, чтобы двигаться дальше, пока все обещания в нашей итерации не будут решены (Mozilla документы на Promise.all являются here):

await Promise.all(middlewares.map(async (middleware) => { 
    await middleware(req, res,() => undefined); 
})); 

И мы должны извлечь это как многоразовые функции:

exports.testExpressValidatorMiddleware = async (req, res, middlewares) => { 
    await Promise.all(middlewares.map(async (middleware) => { 
    await middleware(req, res,() => undefined); 
    })); 
}; 

И теперь мы пришли на моем решении. Если кто-то может улучшить эту реализацию, я очень рад внести изменения.

Смежные вопросы