Sinon间谍不在快速中间件内部调用

我目前正在学习testing一个jwtauthenticationexpress中间件。 我的下一个callback被称为,因为我把一个console.log在那里,但我的sinon间谍断言失败。

有人可以看看这个案子吗?

这是我的testing案例

  it("should call next when the token provided is valid", () => { let token = jwt.sign({}, process.env.JWT); let request = httpMocks.createRequest({ headers: { Authorization: `Bearer ${token}` } }); const next = sinon.spy(); authenticateJwt(request, response, next); expect(next.calledOnce).to.be.true; }); 

这是我的中间件

 import jwt from "jsonwebtoken"; export default function(req, res, next){ const authorizationHeaders = req.headers["authorization"]; let token; if(authorizationHeaders){ token = authorizationHeaders.split(" ")[1]; } if(token){ jwt.verify(token, process.env.JWT, (err, decodedToken) => { if(err){ res.status(401).json({ message: "invalid token provided" }); } else { res.user = decodedToken; console.log("called"); next(); } }); } else { res.status(401).json({ success: false, message: "no token provided" }); } } 

我的console.loglogging正确,但是sinon断言失败。

你的expect可能发生得太早。 在断言已经发生之前,您并不是等待callback发生。

在这个例子中你可能根本不需要sinon,这应该适合你:

 it("should call next when the token provided is valid", () => { let token = jwt.sign({}, process.env.JWT); let request = httpMocks.createRequest({ headers: { Authorization: `Bearer ${token}` } }); return authenticateJwt(request, response, () => { // Do assertions in here }); }); 

也许更好的格式化方法是:

 describe('authenticateJwt middleware', () => { let nextCalled = false; before(() => { let token = jwt.sign({}, process.env.JWT); let request = httpMocks.createRequest({ headers: { Authorization: `Bearer ${token}` } }); return authenticateJwt(request, response, () => { nextCalled = true; }); }) it("should call next when the token provided is valid", () => expect(nextCalled).to.be.true); }); 

这使您可以更灵活地使用断言。 如果因某种原因没有被调用,它也确保它失败。