我正在使用React,Redux,Express,MongoDB和Mocha开发一个全栈式Web应用程序,并且在编写测试以使用Sinon模拟/存根Mongoose模型时遇到了麻烦。目前,我正在尝试测试此路由处理程序以创建用户帐户:
import md5 from "md5";
import { User } from "../models";
import { UserCreationStatuses } from "../../app/store/action-types";
export async function postCreateUser(req, res) {
let { username, password } = req.body;
if (await User.exists({ name: username })) {
return res.status(500).send({ reason: UserCreationStatuses.USERNAME_TAKEN });
} else {
let newUser = new User({
name: username,
passwordHash: md5(password),
});
newUser.save((err) => {
if (err) {
console.info("Error in user creation route:\n", err);
return res.status(500).send({ reason: UserCreationStatuses.SERVER_ERROR });
}
return res.status(200).send();
});
}
}
这是我目前正在坚持的测试(带有省略号,其中省略了其他测试)。我以为我的Mongoose模型“ User”使用exists
函数会引起问题:
import { assert, expect } from "chai";
let chai = require("chai");
let should = require("chai").should();
import httpMocks from "node-mocks-http";
import sinon from "sinon";
import { User } from "../models";
import { UserCreationStatuses } from "../../app/store/action-types";
import { postCreateUser } from "../route-handlers/user-creation";
describe("Route Handlers", function () {
describe("User Creation", function () {
beforeEach(function () {
sinon.stub(User, "exists");
});
afterEach(function () {
User.exists.restore();
});
...
it("should respond with a code of 500 when provided with an existing username, and any password", async function (done) {
this.timeout(10000);
let req = httpMocks.createRequest({
method: "POST",
url: "/create-user",
body: {
username: "ExistingUser",
password: "AnyPassword"
}
});
let res = httpMocks.createResponse();
User.exists.resolves(true);
await postCreateUser(req, res);
res.status.should.equal(500);
done();
});
});
...
});
在我的测试输出中,“应该以500的代码响应”测试给出了此错误:
Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (F:\Web\what-about-a-band-called\src\server\route-handlers\route-handlec.js)
正如您在测试中所见,我曾尝试延长Mocha的超时时间,但这并没有改变任何事情。有什么想法吗?我对使用Sinon存根方法是非常陌生的,并且我假设跳入异步方法和Mongoose会让我有些烦恼。另外,如果这里没有足够的线索,请here is the full repo。
答案 0 :(得分:0)
因此,在进行了一些更多的故障排除之后,我设法使它起作用,但是我对它为什么起作用感到困惑!首先,我在断言中使用res.status
是错误的,我应该一直使用.statusCode
。我现在困惑的部分是,解决实际问题的方法既不调用done()
也不将其作为参数传递给it
的回调。在引入.statusCode
而非.status
之后,出现以下错误:
Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
在删除done()
调用但在回调参数中保留done
之后,我得到以下信息:
Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
完全删除done
可以解决问题!因此,我以为问题出在await postCreateUser(req, res);
上是否正确(或接近正确?)?那个电话既能兑现承诺又能兑现承诺吗?