2017-02-17 6 views
0

Создание API с узлом/Express + Mongo.Почему mongoose findById возвращает ошибку, если ID не найден

Я пишу некоторое модульное тестирование и я заметил, если я пытаюсь получить /profile/1 для _id=1 (я позволил Монго поместить идентификатор по умолчанию, так что я не могу иметь _id=1) я получил эту ошибку

MongooseError: Cast to ObjectId failed for value "1" at path "_id"

Я думал, что у меня будет пустой объект User.

function getProfile(req, res) { 
    const userId = req.params.userId 

    User.findById(userId, "-password", (err, user) => { 
    if (err) { 
     console.log(err); 
     res.status(400) 
     res.json({ 
     success: false, 
     err 
     }) 
     res.end() 
     return 
    } 

    if (!user) { 
     res.status(404) 
     res.json({ 
     success: false, 
     message: `Cannot find an User with the userId: ${userId}` 
     }) 
     res.end() 
     return 
    } 

    res.json({ 
     success: true, 
     user: user 
    }) 
    res.end() 
    return 
    }) 
} 

Мой тест:

describe('Test /profile route',() => { 

    it('shouldn\'t find Joe Doe\'s profile with a wrong ID\n', (done) => { 
     chai.request(server) 
     .get(`/profile/1`) 
     .end((err, res) => { 
     expect(res).to.have.status(404) 
     done() 
     }) 
    }) 

Я думал, что есть ошибка 404 (второй, если, и я знаю, что это не правильный код ошибки, просто быстрый способ для меня, чтобы увидеть, где мой тест идет), но я получил 400 -> означает, что ошибка возвращается.

Я прочитал документацию по mongoose, и я действительно не вижу, чтобы они объясняли возвращаемое значение различными методами.

+0

Какой раздел вашего кода было достигнуто, что бросает эту ошибку? – brandonscript

+0

Похоже, проблема связана с типом - похоже, что это Int, но ожидает ObjectId. Вы используете TypeScript? – brandonscript

+0

Я забыл поставить свой тестовый код извините. И нет, я не использую TypeScript. (Я слышал об этом, но я все еще не читал об этом, если честно) – Ragnar

ответ

1

Проблема в том, что '1' не является допустимым идентификатором объекта mongoose. Поэтому он пытается сравнивать разные типы.

Попытка приведения его к объекту идентификатор так:

userId = mongoose.Types.ObjectId(userId) 

, а затем запустить ваш запрос

User.findById(userId, "-password", (err, user) => { .... }); 
+0

Хорошо, это проблема типа. Поэтому, если у меня есть запрос POST с «userId»: «12345», я должен передать его ObjectId? – Ragnar

+1

Если его тип не является ObjectId, тогда да, вам нужно его бросить. По крайней мере, по моему опыту я всегда должен был. –