У меня есть функция, которую я хочу протестировать с помощью шутки, функция в основном выполняет некоторую проверку токенов и принимает 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 не является функцией
когда я удалил .send () из res.status в коде, тест прошел.
Я пытался выяснить, как имитировать как status (), так и send () в объекте res. но решения пока не нашел.
Tnx



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Думаю, проблема в том, что в результате 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: Не тестировал код :)
вы можете создать цепочку фиктивных классов и тестов, независимо от того, выполняются ли функции или нет.
вот пример.
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;
});
}
а теперь используйте этот фиктивный класс для тестирования. и проверьте, что данная функция выполнилась с заданным результатом или нет. пример как
it("should not call next function, and return 401, if token has not been found", async () => {
let res = new MockResponse(); // here i initialised instance of class
let next = jest.fn();
let req = {cookies:""} // header or cookies where you are receiving token here in my case empty.
await authentication(req, res, next); // here i used my mock res class
expect(next).not.toHaveBeenCalled(); // you must check that next will not be called.
expect(res.status).toHaveBeenCalledWith(401);//you can check result of status
expect(res.send).toHaveBeenCalledWith("not authenticated");// send() message in your function
});
Это сработало! я не знал, что мне нужно вложить функции. tnx для примера!