강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

승현님의 프로필 이미지
승현

작성한 질문수

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지

통합 테스트 해보기

11.3 통합테스트 중 TypeError: model.initiate is not a function

해결된 질문

작성

·

677

·

수정됨

0

질문할까 고민하다가 용기내어 질문드려봅니다..!

11장 통합테스트 중 나타난 에러입니다.

npm test 를 입력하면 나오는 에러입니다.

> nodebird@0.0.1 test
> jest

 PASS  models/user.test.js
 PASS  services/user.test.js
 PASS  middlewares/index.test.js
 FAIL  routes/auth.test.js
  ● Test suite failed to run

    TypeError: model.initiate is not a function

      22 |     console.log(file, model.name);
      23 |     db[model.name] = model;
    > 24 |     model.initiate(sequelize);
         |           ^
      25 |   });
      26 |
      27 | Object.keys(db).forEach(modelName => { // associate 호출

      at initiate (models/index.js:24:11)
          at Array.forEach (<anonymous>)
      at Object.forEach (models/index.js:20:4)
      at Object.require (routes/auth.test.js:2:23)

Test Suites: 1 failed, 3 passed, 4 total
Tests:       9 passed, 9 total
Snapshots:   0 total
Time:        0.725 s, estimated 1 s

현재 에러는 model.initiate가 함수화가 되지 않았다고 나타는거 같습니다.
model.initiate가 존재하는 index.js입니다.

const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];

const db = {};
const sequelize = new Sequelize(
  config.database, config.username, config.password, config,
);

db.sequelize = sequelize;

const basename = path.basename(__filename);
fs
  .readdirSync(__dirname) 
  .filter(file => { 
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => { 
    const model = require(path.join(__dirname, file));
    console.log(file, model.name);
    db[model.name] = model;
    model.initiate(sequelize); // 오류 발생시점
  });

Object.keys(db).forEach(modelName => { 
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

module.exports = db;

11.3 강의를 보는 중이며 auth.test.js 코드를 작성중입니다
작성중인 auth.test.js는 아래와 같습니다.

const app = require('../app');
const request = require('supertest');
const { sequelize } = require('../models');

beforeAll(async () => {
  await sequelize.sync()
})

beforEach(() => {
  
});

describe('POST /join', () => {
  test('로그인 안 했으면 가입', (done) => {
    request(app).post('/auth/join')
      .send({
        email: 'choibo@naver.com',
        nick: 'bobobo',
        password: 'choibo11'
      })
      .expect('Location', '/')
      .expect(302, done)
  })
})

describe('POST /login', () =>{
  test('로그인 수행', (done) => {
    request(app).post('/auth/login')
      .send({
        email: 'choibo@naver.com',
        password: 'choibo11'
      })
      .expect('Location', '/')
      .expect(302, done)
  })
});

afterEach(() => {});

aftereAll(() => {

});

 

이부분에서 에러가 발생한다고 나타나있습니다.

const { sequelize } = require('../models');

답변 2

0

승현님의 프로필 이미지
승현
질문자

감사합니다 강사님! 질문드리고 이제야 확인했습니다!! 현재 test 파일 제외하고 진행하니 모두 잘 작동하는것을 확인할 수 있었습니다!

0

승현님의 프로필 이미지
승현
질문자

예전의 강사님께서 initiate를 init으로 사용하다는 기억이 있어서 인터넷에 찾아보니 init으로 바꿔주면 도움이 될거라는 글을 보고 바꿔봤습니다.
index.js에서 코드를 수정했습니다.

...
const basename = path.basename(__filename);
fs
  .readdirSync(__dirname) // 현재 폴더의 모든 파일을 조회
  .filter(file => { // 숨김 파일, index.js, js 확장자가 아닌 파일 필터링
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => { // 해당 파일의 모델 불러와서 init
    const model = require(path.join(__dirname, file));
    console.log(file, model.name);
    db[model.name] = model;
    model.init(sequelize);
  });
...

이때 나오는 에러 메세지입니다.

 

 PASS  services/user.test.js
 PASS  middlewares/index.test.js
 FAIL  routes/auth.test.js
  ● Test suite failed to run

    No Sequelize instance passed

      22 |     console.log(file, model.name);
      23 |     db[model.name] = model;
    > 24 |     model.init(sequelize);
     25 |   });
      26 |
      27 | Object.keys(db).forEach(modelName => { // associate 호출

      at Function.init (node_modules/sequelize/src/model.js:960:13)
      at init (models/index.js:24:11)
          at Array.forEach (<anonymous>)
      at Object.forEach (models/index.js:20:4)
      at Object.require (app.js:8:23)
      at Object.<anonymous> (routes/auth.test.js:1:30)

Test Suites: 1 failed, 3 passed, 4 total
Tests:       9 passed, 9 total
Snapshots:   0 total
Time:        0.733 s, estimated 1 s
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

개별 모델들 소스코드를 봐야할 것 같은데요. 하나만 올려주세요.

승현님의 프로필 이미지
승현
질문자

models/user.js 파일입니다!

const Sequelize = require('sequelize');

class User extends Sequelize.Model {
  static initiate(sequelize) {
    User.init({
      email: {
        type: Sequelize.STRING(40),
        allowNull: true,
        unique: true,
      },
      nick: {
        type: Sequelize.STRING(15),
        allowNull: false,
      },
      password: {
        type: Sequelize.STRING(100),
        allowNull: true,
      },
      provider: {
        type: Sequelize.ENUM('local', 'kakao'),
        allowNull: false,
        defaultValue: 'local',
      },
      snsId: {
        type: Sequelize.STRING(30),
        allowNull: true,
      },
    }, {
      sequelize,
      timestamps: true,
      underscored: false,
      modelName: 'User',
      tableName: 'users',
      paranoid: true,
      charset: 'utf8',
      collate: 'utf8_general_ci',
    });
  }

  static associate(db) {
    db.User.hasMany(db.Post);
    db.User.belongsToMany(db.User, {
      foreignKey: 'followingId',
      as: 'Followers',
      through: 'Follow',
    });
    db.User.belongsToMany(db.User, {
      foreignKey: 'followerId',
      as: 'Followings',
      through: 'Follow',
    });
  }
};

module.exports = User;
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

이 경우 model.initiate 하는 게 맞습니다. 콘솔 로그 찍었는데 콘솔에 아무것도없나요?

승현님의 프로필 이미지
승현
질문자

제가 제대로 이해한게 맞는지 모르겠지만.. 콘솔을 한번 찍어봤습니다.

 ✘ choebohyeon@choebohyeon-ui-MacBookAir  ~/NodeStudy/Lecture/ch.09   main ±  node auth.test.js
node:internal/modules/cjs/loader:1051
  throw err;
  ^

Error: Cannot find module '/Users/choebohyeon/NodeStudy/Lecture/ch.09/auth.test.js'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15)
    at Module._load (node:internal/modules/cjs/loader:901:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
    at node:internal/main/run_main_module:23:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

Node.js v20.5.0

혹시나 이렇게 확인하는게 아니면 다시 찾아보겠습니다!

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

npm test만 했을 때 콘솔 안 찍히나요? 아니면 에러나는 부분을 주석처리하면 콘솔 찍힐 겁니다.

승현님의 프로필 이미지
승현
질문자

계속해서 에러나는곳 주석처리하며 에러를 찾아봤습니다. 제일 의심되는 console.log는

    console.log
      user.js User

      at log (models/index.js:22:13)
          at Array.forEach (<anonymous>)

    console.log
      user.test.js undefined

      at log (models/index.js:22:13)
          at Array.forEach (<anonymous>)

이것입니다. model/index.js에서 제가 찍은 console.log 위치와 동일하며 user.test.js가 정의 되어 있지 않다고 나타납니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

찾았네요. test 파일도 제외하고 require해야 합니다. filter에 추가하세요. 참고로 이 부분 강의에 나와있을 겁니다.

승현님의 프로필 이미지
승현
질문자

아.. 감사합니다..!! 제가 다시들어보며 틀린위치를 찾아보도록하겠습니다! 늦은시간에 정말 감사합니다!

승현님의 프로필 이미지
승현
질문자

강사님 추가 질문이 있어서 답글 작성해봅니다!
강의를 따라 config/config.json 파일에서 test 부분을 수정했습니다.

{
  "development": {
    "username": "root",
    "password": "nodejs",
    "database": "nodebire",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
"test": {
    "username": "root",
    "password": "nodejs",
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
...

이후 터미널에서
npx sequelize db:create --env test를 입력하면

  ✘ choebohyeon@choebohyeon-ui-MacBookAir  ~/NodeStudy/Lecture/ch.09   main ±  npx sequelize db:create --env test 

Sequelize CLI [Node: 20.5.0, CLI: 6.6.1, ORM: 6.35.1]

Loaded configuration file "config/config.json".
Using environment "test".
Database database_test created.

데이터베이스 만들기가 성공했다고 뜹니다! 실제로 데이터베이스를 확인해보면

테이블이 만들어진것을 확인할 수 있었습니다. 하지만 테이블이 전혀 생성되지 않은 상태입니다.

이 질문은 하는 이유는 어제 답변해주신 방법으로 오류를 잡고자 하였는데

 console.error
      Error: 
          at Query.run (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/sequelize/src/dialects/mysql/query.js:46:25)
          at /Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/sequelize/src/sequelize.js:650:28
          at processTicksAndRejections (node:internal/process/task_queues:95:5)
          at MySQLQueryInterface.select (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/sequelize/src/dialects/abstract/query-interface.js:1001:12)
          at Function.findAll (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/sequelize/src/model.js:1824:21)
          at Function.findOne (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/sequelize/src/model.js:1998:12)
          at Strategy._verify (/Users/choebohyeon/NodeStudy/Lecture/ch.09/passport/localStrategy.js:15:22) {
        name: 'SequelizeDatabaseError',
        parent: Error: Table 'database_test.users' doesn't exist
            at Packet.asError (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/packets/packet.js:728:17)
            at Query.execute (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/commands/command.js:29:26)
            at Connection.handlePacket (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/connection.js:478:34)
            at PacketParser.onPacket (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/connection.js:97:12)
            at PacketParser.executeStart (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/packet_parser.js:75:16)
            at Socket.<anonymous> (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/connection.js:104:25)
            at Socket.emit (node:events:514:28)
            at addChunk (node:internal/streams/readable:343:12)
            at readableAddChunk (node:internal/streams/readable:316:9)
            at Socket.Readable.push (node:internal/streams/readable:253:10)
            at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
          code: 'ER_NO_SUCH_TABLE',
          errno: 1146,
          sqlState: '42S02',
          sqlMessage: "Table 'database_test.users' doesn't exist",
          sql: "SELECT `id`, `email`, `nick`, `password`, `provider`, `snsId`, `createdAt`, `updatedAt`, `deletedAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND `User`.`email` = 'choibo@naver.com');",
          parameters: undefined
        },
        original: Error: Table 'database_test.users' doesn't exist
            at Packet.asError (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/packets/packet.js:728:17)
            at Query.execute (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/commands/command.js:29:26)
            at Connection.handlePacket (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/connection.js:478:34)
            at PacketParser.onPacket (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/connection.js:97:12)
            at PacketParser.executeStart (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/packet_parser.js:75:16)
            at Socket.<anonymous> (/Users/choebohyeon/NodeStudy/Lecture/ch.09/node_modules/mysql2/lib/connection.js:104:25)
            at Socket.emit (node:events:514:28)
            at addChunk (node:internal/streams/readable:343:12)
            at readableAddChunk (node:internal/streams/readable:316:9)
            at Socket.Readable.push (node:internal/streams/readable:253:10)
            at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
          code: 'ER_NO_SUCH_TABLE',
          errno: 1146,
          sqlState: '42S02',
          sqlMessage: "Table 'database_test.users' doesn't exist",
          sql: "SELECT `id`, `email`, `nick`, `password`, `provider`, `snsId`, `createdAt`, `updatedAt`, `deletedAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND `User`.`email` = 'choibo@naver.com');",
          parameters: undefined
        },
        sql: "SELECT `id`, `email`, `nick`, `password`, `provider`, `snsId`, `createdAt`, `updatedAt`, `deletedAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL AND `User`.`email` = 'choibo@naver.com');",
        parameters: {}
      }

라는 오류를 발견하여 문의드립니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

테이블은 서버 한 번이라도 실행하면 알아서 생성됩니다. sequelize.sync() 부분 때문에요

승현님의 프로필 이미지
승현

작성한 질문수

질문하기