[TIL] TDD, Integration test - (3)

Soo·2023년 5월 16일
0
post-thumbnail

🛠 Integration test(통합 테스트)

통합테스트는 모듈을 통합하는 단계에서 수행하는 테스트입니다. 단위테스트를 먼저 수행하여 모듈들이 잘 작동되는 것을 확인했다면, 이제 이 모듈들을 연동시켜 테스트를 수행합니다.
이렇게 연동해서 테스트하는 것이 통합테스트입니다.

❓ 통합테스트를 하는 이유

  • 모듈들의 상호작용이 잘 이루어지는지 검증하기 위해
  • 통합하는 과정에서 발생할 수 있는 오류를 찾기 위해

💡 Supertest란 무엇인가

  • Node.js HTTP 서버를 테스트하기 위해 만들어진 모듈
  • supertest 모듈을 이용해 통합테스트를 보다 쉽게 구현할 수 있습니다.

📚 현재 TDD에 대해 학습 중입니다. 직접 테스트코드를 짜보면서 Express Error Handling에 대해 조금 더 깊이 학습 중입니다.

🔴 Express 에러 처리에 대해

const app = require('express')();

app.get('*', function(req, res, next) {
  // This middleware throws an error, so Express will go straight to
  // the next error handler
  throw new Error('woops');
});

💡 짚고 넘어가기

  • 이렇게 이 미들웨어에 에러가 발생하면 Express는 이 에러를 Handler로 보내준다.
app.get('*', function(req, res, next) {
  // This middleware is not an error handler (only 3 arguments),
  // Express will skip it because there was an error in the previous
  // middleware
  console.log('this will not print');
});

💡 짚고 넘어가기

  • 위에 에러가 발생해 에러핸들러로 바로 가야하기 때문에 이 미들웨어는 생략해준다.
  • 왜냐하면, 이 미들웨어는 에러핸들러가 아니기 때문
app.use(function(error, req, res, next) {
  // Any request to this server will get here, and will send an HTTP
  // response with the error message 'woops'
  res.json({ message: error.message });
});

app.listen(3000);

💡 짚고 넘어가기

  • 에러핸들러는 이렇게 4개의 인자가 들어간다.
  • 그래서 첫 번째 미들웨어에서 발생한 에러 메세지를 이 곳에서 처리해준다.

원래는 위에서처럼 에러 처리를 해주면 되지만, 비동기 요청으로 인한 에러를 이렇게 처리해주면 에러 처리기에서 Error message를 받지 못하기 때문에 서버가 Crash 되버린다.

const app = require('express')();

app.get('*', function(req, res, next) {
  // Will crash the server on every HTTP request
  setImmediate(() => { throw new Error('woops'); });
});

app.use(function(error, req, res, next) {
  // Won't get here, because Express doesn't catch the above error
  res.json({ message: error.message });
});

app.listen(3000);

🟡 해결방안

const app = require('express')();

app.get('*', function(req, res, next) {
  // Reporting async errors *must* go through `next()`
  setImmediate(() => { next(new Error('woops')); });
});

app.use(function(error, req, res, next) {
  // Will get here
  res.json({ message: error.message });
});

app.listen(3000);

🟢 해야할 일

1️⃣ Product 데이터를 DB에 넣기
2️⃣ 통합 테스트 작성 (아래 코드 참고)

it("should return 500 on POST /api/products", async () => {
    const response = await request(app)
    .post('/api/products')
    .send({ name: "soogineer" })
    expect(response.statusCode).toBe(500);

    console.log('response.body', response.body)

    expect(response.body).toStrictEqual({ message: "Product validation failed: description: Path `description` is required."})
});

3️⃣ 이미 작성되어 있는 실제 코드

exports.createProduct = async (req, res, next) => {
  try {
    const createdProduct = await productModel.create(req.body);
    // console.log("createdProduct", createdProduct);
    res.status(201).json(createdProduct);
  } catch (error) {
    next(error);
  }
};

reference: https://thecodebarbarian.com/80-20-guide-to-express-error-handling.html

profile
Soogineer's Devlog

0개의 댓글