#node.js #unit-testing #jestjs #sequelize.js
Вопрос:
Я работаю над некоторыми модульными тестами для проекта, и у меня возникла странная проблема, которую я никак не могу понять. Тест, похоже, изменяет ценность моего макета и проходит, когда этого не должно быть, и я не могу понять, что его вызывает. Код выглядит следующим образом:
controller.js
const userModel = require('../models').users;
module.exports = {
async getUserByID(req, res) {
try {
var user = await userModel.findOne({
where: { id: req.params.id }
});
res.status(201).send(user);
catch (error) {
res.status(500).send(error)
}
},
async getUserByEmail(req, res) {
try {
var user = await userModel.findOne({
where: { email: req.params.email }
});
if (user) {
res.status(201).send(user);
} else {
res.status(404).send({error: 'Error: User account for email ' req.params.email ' does not exist.'})
}
catch (error) {
res.status(500).send(error)
}
}
}
controller.test.js
const controller = require('../controllers/controller');
const httpMocks = require('node-mocks-http');
//mock for main model that my controller function uses
jest.mock('../models/users', () => {
const SequelizeMock = require('sequelize-mock');
const dbMock = new SequelizeMock();
return dbMock.define('users', {
id: 1,
name: 'Tony',
email: 'test1@gmail.com',
uid: '12345'
})
});
//mock for model that's associated to my users model
jest.mock('../models/user_prefs', () => {
const SequelizeMock = require('sequelize-mock');
const dbMock = new SequelizeMock();
return dbMock.define('user_prefs', {
id: 1,
uid: '12345',
notification_settings: {}
})
});
describe('controller.js unit tests', () => {
beforeEach(() => {
jest.clearAllMocks();
})
//first test which is working fine now
describe('getUserByID', () => {
it('should get user from mock', () => {
var req = httpMocks.createRequest({
params: {
id: 1
}
});
var res = httpMocks.createResponse();
controller.getUserByID(req, res).then(() => {
expect(res._getData()._values.name).toBe('Tony');
})
});
});
//second test that is causing me problems
describe('getUserByEmail', () => {
it('should get user from mock corresponding to entered email, or send error message if user does not exist', () => {
var req = httpMocks.createRequest({
params: {
//email that does not match the mock, testing fail case first
email: 'testemail@gmail.com'
}
});
var res = httpMocks.createResponse();
controller.getUserByEmail(req, res).then(() => {
expect(res._getData()._values.email).toEqual('testemail@gmail.com');
})
});
});
});
пакет.json
"scripts": {
"test": "jest --config ./jest.config.js --forceExit --coverage"
}
jest.config.js
module.exports = {
testEnvironment: "node"
}
Проблема, с которой я сейчас сталкиваюсь, связана со вторым модульным тестом. Судя по тому, как я его настроил, я ожидал бы, что он потерпит неудачу, потому что у пользователя в моем макете нет этого электронного письма, но тест прошел. Пытаясь выяснить, что происходит, я console.log(res)
ожидал увидеть статус:404, если он попадет в соответствующий кодовый блок контроллера, но вместо этого статус был 201. Я сделал еще console.log(res._getData()._values)
кое-что, чтобы посмотреть, что я получил обратно, и он возвращал следующее в консоль:
console.log
{ id: 1,
name: 'Tony',
email: 'testemail@gmail.com,
uid: 12345
}
Это похоже на то, что он забрал пользователя из моего макета и изменил значение для электронной почты, в результате чего он никогда не попадал в инструкцию else в моей функции контроллера. Кто-нибудь имеет хоть малейшее представление о том, что здесь происходит? Заранее спасибо за любую помощь, которую кто-либо может предложить.
Комментарии:
1. попробуйте добавить параметр «готово» в свой тест и вызвать done() после вашего ожидания, так как это асинхронные коды, и эти тесты никогда не завершатся неудачей.