Тестирование проверок MongooseJs
Кто-нибудь знает, как проверить валидации Mongoose?
Пример, у меня есть следующая схема (как пример):
var UserAccount = new Schema({
user_name : { type: String, required: true, lowercase: true, trim: true, index: { unique: true }, validate: [ validateEmail, "Email is not a valid email."] },
password : { type: String, required: true },
date_created : { type: Date, required: true, default: Date.now }
});
Метод validateEmail определяется так:
// Email Validator
function validateEmail (val) {
return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(val);
}
Я хочу проверить проверки. Конечным результатом является то, что я хочу иметь возможность проверять валидации, и в зависимости от того, что происходит, я могу написать другие тесты, которые проверяют взаимодействие между этими частями кода. Пример: пользователь пытается зарегистрироваться с тем же именем пользователя, которое используется (электронная почта уже используется). Мне нужен тест, который я действительно могу перехватить или увидеть, что проверка работает БЕЗ попадания в БД. Я НЕ хочу бить Монго во время этих тестов. Это должны быть тесты UNIT, а не интеграционные тесты.:)
Спасибо!
2 ответа
У меня недавно была такая же проблема.
Прежде всего, я бы порекомендовал тестировать валидаторы самостоятельно. Просто переместите их в отдельный файл и экспортируйте имеющиеся у вас функции проверки.
Это позволяет легко разделять ваши модели на отдельные файлы, потому что вы можете использовать эти валидаторы в разных моделях.
Вот пример тестирования валидаторов самостоятельно:
// validators.js
exports.validatePresenceOf = function(value){ ... }
exports.validateEmail = function(value){ ... }
Вот пример теста для этого (с помощью mocha+should):
// validators.tests.js
var validator = require('./validators')
// Example test
describe("validateEmail", function(){
it("should return false when invalid email", function(){
validator.validateEmail("asdsa").should.equal(false)
})
})
Теперь самое сложное:)
Чтобы проверить правильность ваших моделей без доступа к базе данных, есть функция проверки, которая может быть вызвана непосредственно в вашей модели.
Вот пример того, как я в настоящее время делаю это:
describe("validating user", function(){
it("should have errors when email is invalid", function(){
var user = new User();
user.email = "bad email!!"
user.validate(function(err){
err.errors.email.type.should.equal("Email is invalid")
})
})
it("should have no errors when email is valid", function(){
var user = new User();
user.email = "test123@email.com"
user.validate(function(err){
assert.equal(err, null)
})
})
})
Обратный вызов валидатора возвращает объект ошибки, который выглядит примерно так:
{ message: 'Validation failed',
name: 'ValidationError',
errors:
{ email:
{ message: 'Validator "Email is invalid" failed for path email',
name: 'ValidatorError',
path: 'email',
type: 'Email is invalid'
}
}
}
Я все еще новичок в nodeJS и mongoose, но именно так я тестирую свои модели + валидаторы, и, похоже, до сих пор получалось неплохо.
Вы должны использовать метод validate() в качестве обещания и протестировать его с помощью инструмента, который делает утверждения для асинхронного содержимого (например, Chai as Promised).
Прежде всего, потребуйте библиотеку обещаний и переключитесь на поставщика обещаний (например, Q):
mongoose.Promise = require('q').Promise;
Потом просто используйте утверждения об обещаниях:
it('should show errors on wrong email', function() {
user = new UserModel({
email: 'wrong email adress'
});
return expect(user.validate()).to.be.rejected;
});
it('should not show errors on valid email adress', function() {
user = new UserModel({
email: 'test@test.io'
});
return expect(user.validate()).to.be.fulfilled;
});