0

我有一个端点,我在 2 个不同的描述上调用两次以测试不同的响应

const express = require("express");
const router = express.Router();
const fs = require("fs");
const multer = require("multer");
const upload = multer({ dest: "files/" });
const csv = require("fast-csv");

let response = { message: "success" }
router.post("/post_file", upload.single("my_file"), (req, res) => {
    let output = get_output(req.file.path);
    fs.unlinkSync(req.file.path);

    if(output.errors.length > 0) response.message = "errors found";

    res.send(JSON.stringify(response))
})


const get_output = (path) => {

  let errors = []
  let fs_stream = fs.createReadStream(path);
  let csv_stream = csv.parse().on("data", obj => {
                   if(!is_valid(obj)) errors.push(obj);
            });
  

  fs_stream.pipe(csv_stream);

  return {errors};
}

const is_valid = (row) => {
   console.log("validate row")
   
   // i validate here and return a bool
}

我的单元测试

const app = require("../server");
const supertest = require("supertest");
const req = supertest(app);

describe("parent describe", () => {

  describe("first call", () => {   
      const file = "my path to file"

      // this call succeeds
    it("should succeed", async (done) => {
      let res = await req
        .post("/post_file")
        .attach("my_file", file);
     
      expect(JSON.parse(res.text).message).toBe("success")
      done();
     });
   })

    describe("second call", () => {   
      const file = "a different file"

    // this is where the error starts
    it("should succeed", async (done) => {
      let res = await req
        .post("/post_file")
        .attach("my_file", file);
     
      expect(JSON.parse(res.text).message).toBe("errors found")
      done();
     });
   })
})

// csv file is this

NAME,ADDRESS,EMAIL
Steve Smith,35 Pollock St,ssmith@emailtest.com

我得到以下

测试完成后无法登录。您是否忘记在测试中等待异步内容?试图记录“验证行”。

4

1 回答 1

1

问题是被测试的路由执行不正确,它异步工作但不等待get_output结束并以错误的响应同步响应。测试只是显示console.log在测试结束后被异步调用。

一致使用 Promise 是保证正确执行顺序的可靠方法。流需要被承诺被链接:

router.post("/post_file", upload.single("my_file"), async (req, res, next) => {
  try {
    let output = await get_output(req.file.path);
    ...
    res.send(JSON.stringify(response))
  } catch (err) {
    next(err)
  }
})    

const get_output = (path) => {
  let errors = []
  let fs_stream = fs.createReadStream(path);
  return new Promise((resolve, reject) => {
    let csv_stream = csv.parse()
    .on("data", obj => {...})
    .on("error", reject)
    .on("end", () => resolve({errors}))
  });
}

async并且done不应该混合在测试中,因为它们服务于相同的目标,如果done无法访问,这可能会导致测试超时:

it("should succeed", async () => {
  let res = await req
    .post("/post_file")
    .attach("my_file", file);
 
  expect(JSON.parse(res.text).message).toBe("success")
});
于 2020-07-30T07:41:01.593 回答