묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결코로나맵 개발자와 함께하는 지도서비스 만들기 1
코드를 다운받을수 있나요?
복습하고 싶은데 전체코드를 다운받을수 있나요?
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
settings.json에 올려두신 사진과 동일하게 안뜹니다
처음 세팅중인데 읽기전용이라 떠서 커뮤니티에 뜨는대로 따라했는데 올려두신 사진과 같은 내용이 뜨질않아서 어떻게 세틍을 해야하나 질문드려봅니다..
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
401 unauthorized문제
안녕하세요 제로초님 LocalGuard에서 can으로 넘어가지가 않아서 질문드립니다.import { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; @Injectable() export class LocalAuthGuard extends AuthGuard('local') { async canActivate(context: ExecutionContext): Promise<boolean> { const request = context.switchToHttp().getRequest(); console.log('LocalAuthGuard canActivate - request.body:', request); // 추가 로그 console.log('LocalAuthGuard canActivate - before super.canActivate'); // 추가 로그 let can = await super.canActivate(context); console.log(can); if (can) { const request = context.switchToHttp().getRequest(); console.log('login for cookie'); console.log('request.user:', request.user); // 추가 로그 await super.logIn(request); } return true; } } 여기서 보면 requsetbody에는 request.body: { teacherId: 'hee', password: '12534' } 이렇게 제가 설정한값이 들어가고 UnauthorizedException: Unauthorized at LocalAuthGuard.handleRequest (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/@nestjs/passport/dist/auth.guard.js:60:30) at /Users/mac/Desktop/sideProject/piano-erp-back/node_modules/@nestjs/passport/dist/auth.guard.js:44:124 at /Users/mac/Desktop/sideProject/piano-erp-back/node_modules/@nestjs/passport/dist/auth.guard.js:83:24 at allFailed (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/passport/lib/middleware/authenticate.js:110:18) at attempt (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/passport/lib/middleware/authenticate.js:183:28) at strategy.fail (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/passport/lib/middleware/authenticate.js:314:9) at Strategy.authenticate (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/passport-local/lib/strategy.js:75:17) at attempt (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/passport/lib/middleware/authenticate.js:378:16) at authenticate (/Users/mac/Desktop/sideProject/piano-erp-back/node_modules/passport/lib/middleware/authenticate.js:379:7) at /Users/mac/Desktop/sideProject/piano-erp-back/node_modules/@nestjs/passport/dist/auth.guard.js:88:3 { response: { message: 'Unauthorized', statusCode: 401 }, status: 401, options: {}}undefinedteacher.decorator.ts undefined 이렇게 에러가나는데 원인은 잘모르겠습니다. 혹시 어떤부분을 살펴봐야할까요? 추가로 저기이외에 strategy쪽에는 console찍은게 아에 안들어옵니다.
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
그랩마켓 웹 화면 구현하기 코드
섹션 2HTML & CSS 기본그랩마켓 웹 화면 구현하기 코드 복사할 수 있을까요?컴퓨터를 새로 샀는데 굳이 다시 구현 할 필요가 없어서 그렇습니다.
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
가드의 장점에 대해서 질문이 있습니다.
안녕하세요. 유저가 가진 권한에 따른 접근 제어 개발을 하다 문득 궁금한 것이 생겼는데요.유저가 권한을 갖고있는지 확인하고, 접근을 허용/차단 하는 코드를 서비스에서 작성 할 수도 있고, 커스텀 데코레이터를 작성해서 컨트롤러 단에서 막을 수도 있잖아요. 둘 중 어떤 방법이 효율적인 방법인지, 장/단점은 무엇인지가 궁금해졌습니다.곰곰이 생각해봐도 차이가 있는 장/단점을 모르겠네요... 어떤 방법이 더 좋은 방법일까요?
-
미해결코로나맵 개발자가 알려주는 React + Express로 지도서비스 만들기 (Typescript)
MongoDB Compass 관련 질문
MongoDB compass에서 new connection에서 말씀하신 대로 mern, merntest, admin 이렇게 설정해주고, connect 버튼을 눌렀는데 Authentication failed라는 오류가 뜹니다. 어느 부분에서 오류가 난 건가요..?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
next, node 버전 / 폴더 구조 질문 드립니다.
1번 질문next9 버전을 다운받아서 실행 했더니 오류가 나서 찾아봤는데 node버전이 높아서 호환 관련 문제로 실행이 안되는 오류가 있었습니다. next14 버전으로 진행했는데 앞으로도 괜찮나요? 2번 질문pages 폴더안에 index.js파일은 /이고 그 외에 이름은 /profile, /signup 구조인것 같은데 어떤 경우에 폴더구조를 사용하고 어떤 경우에 js파일의 이름을 변경해서 사용해야 하는지 궁금합니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
url 오류 질문있습니다
프론트 axios에서 baseurl을 https://api.count101.shop으로 설정했는데 요청을 보내보니깐 request url이 https://count101.shop/https/api.count101.shop/user/autoLogin 이런식으로 앞에 https://count101.shop이 붙어버리는데 어디를 수정해야 될 지 모르겠습니다,,
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
실시간 채팅방에서 GIF uploads 하면 GIF가 바로 화면에 보이지 않고 새로 고침을 해야 보이는데 어떻게 해야 할까요?
실시간 채팅방 강좌 코드를 작성하여 작동 시켜 본 결과 메시지 전송 까지는 잘 되는 것을 확인 하였는데 GIF 업로드 시 다음 그림과 같은 현상이 발생하고 있습니다그림 하단에 표시한 부분 처럼 처음에 GIF 올리기를 하면 그림이 보이지 않다가 새로 고침을 하면 위의 다른 GIF 처럼 잘 보이긴 하는데 무슨 문제 일까요?참고로 관련 코드를 같이 올립니다chat.html {% extends 'layout.html' %} {% block content %} <h1>{{title}}</h1> <a href="/" id="exit-btn">방 나가기</a> <fieldset> <legend>채팅 내용</legend> <div id="chat-list"> {% for chat in chats %} {% if chat.user === user %} <div class="mine" style="color: {{chat.user}}"> <div>{{chat.user}}</div> {% if chat.gif %}} <img src="/gif/{{chat.gif}}"> {% else %} <div>{{chat.chat}}</div> {% endif %} </div> {% elif chat.user === 'system' %} <div class="system"> <div>{{chat.chat}}</div> </div> {% else %} <div class="other" style="color: {{chat.user}}"> <div>{{chat.user}}</div> {% if chat.gif %} <img src="/gif/{{chat.gif}}"> {% else %} <div>{{chat.chat}}</div> {% endif %} </div> {% endif %} {% endfor %} </div> </fieldset> <form action="/chat" id="chat-form" method="post" enctype="multipart/form-data"> <label for="gif">GIF 올리기</label> <input type="file" id="gif" name="gif" accept="image/gif"> <input type="text" id="chat" name="chat"> <button type="submit">전송</button> </form> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> const socket = io.connect('http://localhost:8005/chat', { path: '/socket.io', }); socket.emit('join', new URL(location).pathname.split('/').at(-1)); socket.on('join', function (data) { const div = document.createElement('div'); div.classList.add('system'); const chat = document.createElement('div'); div.textContent = data.chat; div.appendChild(chat); document.querySelector('#chat-list').appendChild(div); }); socket.on('exit', function (data) { const div = document.createElement('div'); div.classList.add('system'); const chat = document.createElement('div'); div.textContent = data.chat; div.appendChild(chat); document.querySelector('#chat-list').appendChild(div); }); socket.on('chat', function (data) { const div = document.createElement('div'); if (data.user === '{{user}}') { div.classList.add('mine'); } else { div.classList.add('other'); } const name = document.createElement('div'); name.textContent = data.user; div.appendChild(name); if (data.chat){ const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); } else { const gif = document.createElement('img'); gif.sr = '/gif/' + data.gif; div.appendChild(gif); } div.style.color = data.user; document.querySelector('#chat-list').appendChild(div); }); document.querySelector('#chat-form').addEventListener('submit', function (e) { e.preventDefault(); if (e.target.chat.value) { axios.post('/room/{{room._id}}/chat', { chat: this.chat.value, }) .then( () => { e.target.chat.value = ''; }) .catch( (err) => { console.error(err); }); } }); document.querySelector('#gif').addEventListener('change', function (e) { console.log('******',e.target.files); const formData = new FormData(); formData.append('gif', e.target.files[0]); axios.post('/room/{{room._id}}/gif', formData) .then( () => { e.target.file = null; }) .catch( (err) => { console.error(err); }); }); </script> {% endblock %} routes/index.jsconst express = require('express'); const { renderMain, renderRoom, createRoom, enterRoom, removeRoom, sendChat, sendGif } = require('../controllers'); const multer = require('multer'); const fs = require('fs'); const path = require('path'); const router = express.Router(); router.get('/', renderMain); router.get('/room', renderRoom); router.post('/room', createRoom); router.get('/room/:id', enterRoom); router.delete('/room/:id', removeRoom); router.post('/room/:id/chat', sendChat); try {fs.readdirSync('uploads'); } catch (err) { console.error('uploads 폴더가 없어 uploads 폴더를 생성합니다.'); fs.mkdirSync('uploads'); } const upload = multer({ storage: multer.diskStorage({ destination(req, file, done) { done(null, 'uploads/'); }, filename(req, file, done ) { const ext = path.extname(file.originalname); done(null, path.basename(file.originalname, ext) + Date.now() + ext); }, }), limits: {fileSize: 5 * 1024 *1024 }, }) router.post('/room/:id/gif', upload.single('gif'), sendGif); module.exports = router;controllers/index.jsconst Room = require('../schemas/room'); const Chat = require('../schemas/chat'); const { removeRoom: removeRoomService } = require('../services'); exports.renderMain = async ( req, res, next ) => { try{ const rooms = await Room.find({}); res.render('main', {rooms, title: 'GIF 채팅방'}); } catch (error) { console.error(error); next(error); } }; exports.renderRoom = ( req, res, next ) => { res.render('room', { title: 'GIF 채팅방 생성'}); }; exports.createRoom = async ( req, res, next ) => { try{ const newRoom = await Room.create({ title: req.body.title, max: req.body.max, owner: req.session.color, password: req.body.password, //session data 에서 옮 }); const io = req.app.get('io'); io.of('/room').emit('newRoom', newRoom); // 방에 들어가는 부분 if (req.body.password ) { res.redirect(`/room/${newRoom._id}?password=${req.body.password}`); } else { res.redirect(`/room/${newRoom._id}`); } } catch (error) { console.error(error); next(error); } }; exports.enterRoom = async( req, res, next ) => { try{ const room = await Room.findOne({_id: req.params.id}); if (!room){ return res.redirect('/?error=존재하지 않는 방입니다.'); } if (room.password && room.password !== req.query.password ){ return res.redirect('/?error=비밀번호가 틀렸습니다.'); } const io = req.app.get('io'); const { rooms } = io.of('/chat').adapter; if (room.max <= rooms.get(req.params.id)?.size) { return res.redirect('/?error=허용 인원을 초과하였습니다.'); } const chats = await Chat.find({room: room._id }).sort('createdAt'); res.render('chat', { title: 'GIF 채팅방 생성', chats , room, user: req.session.color }); } catch (error) { console.error(error); next(error); } }; exports.removeRoom = async ( req, res, next ) => { try { await removeRoomService(req.params.id ); res.send('ok'); setTimeout(() => { req.app.get('io').of('/room').emit('removeRoom', req.params.id); }, 2000) } catch (error) { console.error(error); next(error); } }; exports.sendChat = async (req, res, next ) =>{ try { const chat = await Chat.create({ room: req.params.id, user: req.session.color, chat: req.body.chat, }); req.app.get('io').of('/chat').to(req.params.id).emit('chat', chat); res.send('ok'); } catch( error ){ console.error(error); next(error); } } exports.sendGif = async (req, res, next ) => { try { const chat = await Chat.create({ room : req.params.id, user: req.session.color, gif: req.file.filename, }) setTimeout(() => { req.app.get('io').of('/chat').to(req.params.id).emit('chat',chat); }, 1000); res.send('ok'); } catch (error) { console.error(error); next(error); } } [제로초 강좌 질문 필독 사항입니다]질문에는 여러분에게 도움이 되는 질문과 도움이 되지 않는 질문이 있습니다.도움이 되는 질문을 하는 방법을 알려드립니다.https://www.youtube.com/watch?v=PUKOWrOuC0c0. 숫자 0부터 시작한 이유는 1보다 더 중요한 것이기 때문입니다. 에러가 났을 때 해결을 하는 게 중요한 게 아닙니다. 왜 여러분은 해결을 못 하고 저는 해결을 하는지, 어디서 힌트를 얻은 것이고 어떻게 해결한 건지 그걸 알아가셔야 합니다. 그렇지 못한 질문은 무의미한 질문입니다.1. 에러 메시지를 올리기 전에 반드시 스스로 번역을 해야 합니다. 번역기 요즘 잘 되어 있습니다. 에러 메시지가 에러 해결 단서의 90%를 차지합니다. 한글로 번역만 해도 대부분 풀립니다. 그냥 에러메시지를 올리고(심지어 안 올리는 분도 있습니다. 저는 독심술사가 아닙니다) 해결해달라고 하시면 아무런 도움이 안 됩니다.2. 에러 메시지를 잘라서 올리지 않아야 합니다. 입문자일수록 에러메시지에서 어떤 부분이 가장 중요한 부분인지 모르실 겁니다. 그러니 통째로 올리셔야 합니다.3. 코드도 같이 올려주세요. 다만 코드 전체를 다 올리거나, 깃헙 주소만 띡 던지지는 마세요. 여러분이 "가장" 의심스럽다고 생각하는 코드를 올려주세요.4. 이 강좌를 바탕으로 여러분이 응용을 해보다가 막히는 부분, 여러 개의 선택지 중에서 조언이 필요한 부분, 제 경험이 궁금한 부분에 대한 질문은 대환영입니다. 다만 여러분의 회사 일은 질문하지 마세요.5. 강좌 하나 끝날 때마다 남의 질문들을 읽어보세요. 여러분이 곧 만나게 될 에러들입니다.6. 위에 적은 내용을 명심하지 않으시면 백날 강좌를 봐도(제 강좌가 아니더라도) 실력이 늘지 않고 그냥 코딩쇼 관람 및 한컴타자연습을 한 셈이 될 겁니다.
-
해결됨비전공자를 위한 진짜 입문 올인원 개발 부트캠프
강의제공자의 답변을 원합니다 AI 답변만 있고 더이상 직접 답변을 안해주시네요?
AI 답변이 어느정도 편리할 수 있단 건 인정하지만, 질문 답변도 강의서비스에 포함된 것인데 어느 순간부터 강의제공자님의 직접답변은 달리지 않고 AI 답변만 달리네요. 그것만으로 전혀 충분하지 않은데 말이죠그리고 AI 답변은 기존 데이터가 없으면 답변을 못해줍니다. 강의제공자로부터 피드백을 받을 수 있을 것을 기대하고 강의를 수강하는데 이렇게 질문답변 조차 제대로 해결이 되지 않고 있는 것은 문제라고 봅니다.몇년 동안 강의를 걸어놓으 실 거면, 그리고 여러 API를 사용하실 거면 적어도 일년에 한번은 UI나 기능에 변화나 업데이트 가 있는지 확인하고 강의에 반영해주셔야 할 것 같은데 아직도 2022년 버전을 그대로 강의에 걸어두셔서 현재 UI와 완전달라 강의 진행이 제대로 안되고 있습니다.이게 정말 제대로 되고 있는게 맞나요? 무료 강의도 아니고 돈내고 듣는 강의에서 기본적인 내용 업데이트 및 강의에 포함된 질문 답변조차 제대로 진행 되지 않는다는 건 매우 실망 스럽습니다.강의 제공자님의 빠른 직접 답변과 피드백 부탁드립니다.
-
미해결이미지 관리 풀스택(feat. Node.js, React, MongoDB, AWS)
강의에 사용된 코드 다운 받는 사이트 주소 있나요?
강의에 사용된 코드 다운 받는 사이트 주소 있나요?
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
Postman UI가 또 바뀌어서 Mockserver 를 찾을 수가 없습니다
제목 그대로 입니다. 가장 최근에 업데이트 해주신게 벌써 2년전인데, 강의를 계속 걸어놓으시려면 적어도 매년 단위로UI 상태에 맞게 해당 부분만이라도 강의를 업데이트 해주셔야 할 것 같습니다.Mock server 부분 도저히 찾지못해 시간만 보내고 진척이 없습니다. 대체 어떻게 해야 하나요?
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
로그 관리에 대해 질문 있습니다.
안녕하세요. 최근에 프로젝트를 완성해서 배포까지 성공리에 마쳤는데요. 이제 운영을 해야하는데 몇가지 궁금한 점이 생겨서 질문 남기게 되었습니다.운영을 하다보면 배포하기 전 진행한 테스트 외에도 예기치 못한 오류가 생길 수 있기때문에 서버에서 로깅하는게 굉장히 중요하다고 생각이 드는데요. 실무에서는 로깅을 따로 어떻게 하는지에 대해 궁금함이 생겼습니다.현재 서비스의 중요한 비즈니스 로직에는 Logger를 사용해서 호출 될 때 마다, 시간과 함께 넘어가는 데이터를 같이 로깅하게끔 개발 해놨습니다. 약간 문제라고 생각되는 것은 에러가 발생 할 때, 호스팅하고있는 온프레미스 서버에 직접 접속해서 도커 컨테이너 로그를 일일이 확인해야 하는 번거로움이 있는 점입니다. 실무에서 모든 개발자들이 이렇게 확인하지 않을 것이라고 생각하는데 보통 실무에서는 어떻게 로그를 관리하시나요? 조언 부탁드립니다!
-
미해결코로나맵 개발자와 함께하는 지도서비스 만들기 2
키워드 검색 데이터 받아오기 강의중 문제 발생
카카오 api 받아서 지도 잘 작동하고 검색창도 떳는데키워드 검색 데이터 받아오기 강의 들으면서 잘 따라갔는데 갑자기 안됩니다 upload.js:1 Uncaught ReferenceError: require is not definedat upload.js:1:20 f12누르니까 이렇게 나옵니다 ㅠㅠ 추가적으로 vs코드에서는파일이 CommonJS 모듈입니다. ES 모듈로 변환될 수 있습니다.ts(80001) 이런 문구가 나오네요 +그래서 upload 파일은 무시하고 지도위에 저장한 데이터 표시하기 강의까지 들었는데 이번엔 main.js:1 Uncaught ReferenceError: require is not defined at main.js:1:20 이렇게 뜨네요 require 함수가 지금까지 잘 되다가 수업이 진행될수록 왜 문제가 될까요 ㅠㅠ
-
해결됨Slack 클론 코딩[백엔드 with NestJS + TypeORM]
CORS 에러 질문 있습니다.
안녕하세요. 프로젝트를 배포하는 과정에서 왜인지 모를 CORS 에러가 계속 생겨서 질문 드립니다.CORS 문제를 해결하기 위해서는 응답 헤더에 Acess-Control-Allow-Origin이 필요한데, nestjs와 같은 was에서 enableCors를 설정해주거나, Nginx의 server 블럭에 add_header를 통해서 헤더를 추가 해 줄 수 있는 것으로 알고 있습니다.웹 서버가 was보다 앞에 있으니까 웹 서버에서 설정해줘야겠다는 생각에 nginx.conf에 allowed_origin은 동적으로 Access-Control-Allow-Origin 헤더의 값을 받기 위해서 설정해뒀습니다.이렇게 작성하고 reload를 해줬는데, 왜인지 응답헤더에 추가한 헤더가 생기지 않습니다...테스트 서버에 위와 같은 설정으로 올렸을 때는 잘 해결됐는데 라이브에 올리니까 이런 문제가 발생하는데 어디를 살펴봐야 할 지 모르겠습니다... access to XMLHttpRequest at '도메인 주소' from origin '서버 ip' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.이런식으로 404에러가 나옵니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
app.js 에서 sequelize 를 가져오는 부분이 models/index.js 있는 sequelize 를 가르키는게 맞나요?
[제로초 강좌 질문 필독 사항입니다]세션 6번app.js 시퀄라이즈 싱크에 관한 문의 입니다.const { sequelize } = require('./models');app.js 에서 시퀄라이즈를 가져오는데 해당 모둘안에는 3개의 파일 있습니다 .( user, comment, index ) index 파일만 실행하면 될거 같은데 sequelize 자져오는 이유가 궁금하고 , 여기서 가르키는 sequelize 가 index에 있는 sequelize 인지 궁금합니다.
-
해결됨비전공자를 위한 진짜 입문 올인원 개발 부트캠프
CRUD에서 CR만 배우는건가요
수정 삭제는 sqlite로 직접 만져야되나요
-
미해결
express vercel 배포 500: INTERNAL_SERVER_ERROR
express 서버를 vercel로 배포 하는데 500에러가 뜨는데 왜 뜨는지 어디가 문제인지 모르겠어요... 도움주실수 있으실까요 ㅠㅠ
-
미해결
express, MySQL 백엔드 배포를 도와주실 분을 찾습니다
[express, MySQL 백엔드 배포를 도와주실 분을 찾습니다]안녕하세요! 현재 취업 준비 중인 프론트엔드 예비 개발자입니다.현재 배포에 난항을 겪고 있어 배포를 도와주실 백엔드 개발자분을 찾습니다.express로 서버 코드는 부족하지만 제가 할 수 있는 한 코드를 작성하였고 로컬에서는 문제가 없었습니다.프론트단은 깃헙 페이지나 vercel로 배포 예정이고 express, MySQL 어떤식으로 배포를 진행할지 모르겠습니다.많이 부족한 취준생이지만 프로젝트에 조금이나마 도움을 주실 수 있는 분이라면 좋겠습니다!제 코드를 보시고 많은 조언과 충고도 해주시면 감사하겠습니다:)⭐ 오픈채팅방https://open.kakao.com/o/g0Tqohbg 해당 링크로 도와주세요!
-
미해결따라하며 배우는 TDD 개발 [2023.11 업데이트]
TypeError: user_model_1.default.create is not a function
학습중 repository pattern을 적용하여 테스트를 적용해 보던 중 TypeError: user_model_1.default.create is not a function 라는 에러와 마주하게 되었습니다.user.repository.tsimport User from "../model/user.model"; export class UserRepository { createUser = async(user) => { const newUser = await User.create({ ...user }) return newUser } findUserById = async(id:string) => { const user = await User.findById('65cba34813b2fbec74a558a8') if(!user) throw new Error('존재하지 않는 유저정보 입니다.') return user } }user.repository.test.tsimport { UserRepository } from "../../app/repository/user.repository" const createMock = jest.fn() const findByIdMock = jest.fn() jest.mock("../../app/model/user.model", () => { return { User: jest.fn(() => { return { create:createMock, findById:findByIdMock } }) } }) describe('user repository Create', () => { let sut:UserRepository; const newUser = { id:"abcdefrwgsf123123", name:"test name", email:"test@nanana.com" } beforeEach(() => { sut = new UserRepository() }) afterEach(() => { jest.clearAllMocks() }) it('create api', async () => { createMock.mockReturnValueOnce(newUser) const actual = await sut.createUser({name:newUser.name, email:newUser.email}) expect(createMock).toHaveBeenCalledTimes(1) expect(actual).toStrictEqual(newUser) expect(createMock).toHaveBeenCalledWith({name:newUser.name, email:newUser.email}) }) }) jest실행시 create api의 createMock.mockReturnValue() 까지는 실행이되지만 await sut.createUser() 부분에서 에러가 나는것으로 확인되었습니다.