почему Jest жалуется на необработанный асинхронный код, хотя все обрабатывается

#node.js #mongodb #express #jestjs #supertest

Вопрос:

У меня есть blog.js файл определяется следующим образом

 const blogRouter = require("express").Router();
const Blog = require("../models/blog");

blogRouter.get("/", async (req, res) => {
  try {
    const result = await Blog.find({});
    res.json(result);
  } catch (err) {
    res.status(400).json({ err: err });
  }
});

blogRouter.post("/", async (req, res, next) => {
  if (!req.body.title || req.body.url) {
    return res.status(400).json({ error: "an error occured " });
  }
  if (!req.body.likes) {
    req.body.likes = 0;
  }
  const blog = new Blog(req.body);

  try {
    const result = await blog.save();
    res.json(result);
  } catch (err) {
    res.status(400).json({ err: err });
    next(err);
  }
});
//*
blogRouter.delete("/:id", async (req, res, next) => {
  const id = req.params.id;

  try {
    const results = await Blog.findByIdAndRemove(req.params.id);
    if (results) {
      res.status(200).json(results).end();
    } else {
      res.status(400).json({ err: "an error occured" });
    }
  } catch (err) {
    next(err);
  }
});
//*/
module.exports = blogRouter;
 

теперь я создал вспомогательную функцию тестирования, подобную этой .

 const getAllBlog = async () => {
  const result = await Blog.find({});
  return result.map((r) => r.toJSON());
};
 

а затем я написал тесты для большей части обработки маршрутов, как это

 const mongoose = require("mongoose");
const supertest = require("supertest");
const testHelper = require("./test_helper");
const app = require("../app");

const api = supertest(app);

const Blog = require("../models/blog");

beforeEach(async () => {
  await Blog.deleteMany({});
  console.log("cleared");

  const blogObject = testHelper.testBlogs.map((blog) => {
    return new Blog(blog);
  });
  const promiseArray = blogObject.map((obj) => {
    return obj.save();
  });
  await Promise.all(promiseArray);
  console.log("done");
});

test("return correct amount of post", async () => {
  const response = await api
    .get("/api/blog")
    .expect(200)
    .expect("Content-Type", /application/json/);
  const blogdb = await testHelper.getAllBlog();
  expect(response.body).toHaveLength(blogdb.length);
});

test("creation of new blog works", async () => {
  const blogObj = {
    title: "a funny blog",
    url: "https://zomato.com",
    author: "somegirl",
    likes: 20,
  };
  const blogs = await testHelper.getAllBlog();
  await api
    .post("/api/blog")
    .send(blogObj)
    .expect(200)
    .expect("Content-Type", /application/json/);

  const result = await api.get("/api/blog").expect(200);

  expect(result.body).toHaveLength(blogs.length   1);

  const obj = result.body.map((r) => r.title);
  expect(obj).toContain("a funny blog");
});
test("default likes value is  0", async () => {
  const blogObj = {
    title: "a funny blog",
    url: "https://zomato.com",
    author: "somegirl",
  };
  await api
    .post("/api/blog")
    .send(blogObj)
    .expect(200)
    .expect("Content-Type", /application/json/);
  const result = await testHelper.getAllBlog();

  const arra = result.map((r) => r.likes);
  expect(arra).toContain(0);
});

test("unique identifer is id", async () => {
  const response = await api
    .get("/api/blog")
    .expect(200)
    .expect("Content-Type", /application/json/);

  expect(response.body[0].id).toBeDefined();
});

test("lack of title and url returns 400", async () => {
  const obj = {
    likes: 50,
    author: "the ment",
  };

  await api.post("/api/blog").send(obj).expect(400);
});

//*
describe("delete operations test", () => {
  test("deleting a particular blogs works", async () => {
    const firstresults = await testHelper.getAllBlog();

    const idArray = firstresults.map((r) => r.id);
    console.log(idArray);

    const value = await api.get("/api/blog").expect(204);

    const secondResult = await testHelper.getAllBlog();

    expect(secondResult).toHaveLength(firstresults.length - 1);
  });
});

//*/
afterAll(() => {
  mongoose.connection.close();
});
 

Every test passes except for the last one. The last test doesn’t even fail, jest complains of an error about an unhandled asynchronous code.

 Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

  ●  Cannot log after tests are done. Did you forget to wait for something async in your test?
    Attempted to log "connection succesful".

      12 |
      13 | const blogRouter = require('./controllers/blog')
    > 14 |
         | ^
      15 |
      16 |
      17 |

      at CustomConsole.log (node_modules/@jest/console/build/CustomConsole.js:187:10)
      at app.js:14:11
 

I can debug why that last test causes this error, I have done and googled as much as I can and I can’t seem to find a fix.