英文:
Jest.spyOn return an error -"Cannot use spyOn on a primitive value; undefined given" Express.js package "express-validator"
问题
在测试期间出现了错误。这个错误的含义是你在尝试使用jest.spyOn
来模拟express-validator
中的validationResult
函数时遇到了问题。错误信息中提到了:
Jest: spyOn could not find an object to spy upon for validationResult()
这意味着jest.spyOn
无法找到要模拟的对象。问题可能是你导入的express-validator
模块不是一个可被jest.spyOn
追踪的对象。
要解决这个问题,你可以尝试以下步骤:
-
确保你正确导入了
express-validator
。你可以检查一下你的导入语句是否正确,或者尝试使用绝对路径来导入,确保路径是准确的。 -
如果你的导入语句是正确的,但仍然出现问题,那么可能是因为模块的导出方式不允许
jest.spyOn
进行模拟。在这种情况下,你可以考虑修改你的代码,以便更容易进行模拟测试。这可能涉及到将某些验证逻辑进行封装,以便更容易进行测试。 -
如果你仍然遇到问题,可以查看
express-validator
的文档或社区支持,以获取有关如何在测试中正确使用它的更多信息。他们可能提供了一些针对测试的最佳实践或示例代码。
根据你的错误信息,这些步骤应该有助于你解决问题并让测试通过。
英文:
I use Express.js, to validate requests, I use a package express-validator. And I want to test the controller:
import { validationResult } from "express-validator";
class RegistrationController {
async registration(req, res, next): Promise<Response> {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next("Houston, we have a problem");
}
return res.status(200).json(true);
} catch (e) {
next(e);
}
}
}
export = new RegistrationController();
This is my test:
import RegistrationController from "./registration.controller";
import validator from "express-validator";
describe("registration", () => {
const { registration } = RegistrationController;
let req = {},
res = {},
next = jest.fn();
it('If errors occur during the request validation process, next("Houston, we have a problem") should be called', async () => {
const validationResultMock = {
isEmpty: () => false,
};
jest
.spyOn(validator, "validationResult")
//@ts-ignore
.mockImplementation(() => validationResultMock);
await registration(req, res, next);
expect(next).toBeCalledWith("Houston, we have a problem");
});
});
During the test, an error falls:
What does this error mean? Am I spying on the package incorrectly? How do I fix it so that the test passes?
答案1
得分: 0
简而言之,我在互联网上没有找到如何监视express-validator
的答案,没有人这样做,他们使用其他方法来测试控制器。
为什么会出现错误,如何解决,我如何测试我的控制器 - 我会在后面写…
这就是我如何回答我的问题:
1. 这个错误是什么意思?我是不是错误地监视了这个包?
我正确地监视了"express-validator"
包中的"validationResult"
方法,问题在于"validationResult"
不是该包的一个方法。
如果你去到"express-validator"
包导入的地址,你会看到:
"validationResult"
是从"express-validator"
包导出的文件的地址。首先,如果你看这个地址下的文件'./validation-result'
,你会看到这里有一个export declare class Result<T = any>
类,它有一个isEmpty()
方法
很可能,这个方法在这样的字符串中使用:
errors.isEmpty()
因此,我们可以得出结论,错误是因为尝试调用一个不存在的"validationResult"
方法,这是"express-validator"
包的特殊结构造成的。
2. 我该如何修复以使测试通过?
我的测试的主要任务是检查代码的这一部分:
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next("Houston, we have a problem");
}
为了确保,如果验证出错,函数调用将起作用:next("Houston, we have a problem")
在互联网上有很多种方法可以做到这一点,但它们都谈到了同一点 - 你需要拿到应用程序并模拟一个错误的请求,然后请求会被处理,控制器将根据指令进行处理。在测试级别上,你将与期望结果进行比较。我找到的最受欢迎的模拟查询的库是"supertest"
,我在我的新测试中使用了它。
例如,这是我的路由看起来像这样:
import express from "express";
import { body } from "express-validator";
// 控制器
import registrationController from "../controllers/registration.controller";
const router = express.Router();
// 注册
router.post(
"/registration",
body("email").isEmail(),
body("password").isLength({ min: 3, max: 32 }),
registrationController.registration
);
export = router;
这是我的新测试:
import express from "express";
import request from "supertest";
描述("RegistrationController", () => {
描述("registration", () => {
const app = express();
it("如果在执行方法时出现错误,应该发生next('Houston, we have a problem')调用", async () => {
const next = jest.fn();
尝试 {
// 传递一个空请求给不会通过验证的应用程序
await request(app).post("/registration");
} 捕获(e) {
// 我们将请求由控制器处理的结果与期望的结果进行比较
期望(next).toHaveBeenCalledWith("Houston, we have a problem");
}
});
});
});
我们很高兴一切都对我们起作用
如果你知道如何正确地监视来自"express-validator"
包的"ValidationResult"
方法,以避免出现错误,请分享你的方法。我在互联网上没有找到这样的方法,我会非常感激你
英文:
In short, I have not found an answer on the Internet how to spy on express-validator
, no one does this, they use other ways of testing controllers.
Why the error appears, how to fix it, how I tested my controller - I will write further...
That's how I can answer my questions:
1. What does this error mean? Am I spying on the package incorrectly?
I am correctly spying on the "validationResult"
method in the "express-validator"
package, the problem is that "validationResult"
is not a method of the package.
If you go to the address where the "express-validator"
package is imported from, you can see:
That "validationResult"
is the address of the file that is exported from the "express-validator"
package. This is firstly, and secondly, if you look at the file itself at the address './validation-result'
, that export declare class Result<T = any>
class is located here, which has the isEmpty()
method
Most likely, this method is used in the string:
errors.isEmpty()
Therefore, we can conclude that the error appears due to the special structure of the "express-validator"
package when I try to follow a method "validationResult"
that does not exist.
2. How do I fix it so that the test passes?
The main task of my test was to check this part of the code:
const errors = validationResult(req);
if (!errors.isEmpty()) {
return next("Houston, we have a problem");
}
To be sure, if validation went wrong, the function call will work: next("Houston, we have a problem")
There are quite a lot of ways to do this on the Internet, but they all talked about the same thing - you need to take the application and simulate an incorrect request, then the request will be processed and the controller will process it according to the instructions. And at the test level, you will make a comparison with the expected result. The most popular library for query simulation that I found was "supertest"
, which I used in my new test.
For example, this is how my routes look like:
import express from "express";
import { body } from "express-validator";
// CONTROLLERS
import registrationController from "../controllers/registration.controller";
const router = express.Router();
// REGISTRATION
router.post(
"/registration",
body("email").isEmail(),
body("password").isLength({ min: 3, max: 32 }),
registrationController.registration
);
export = router;
And this is my new test:
import express from "express";
import request from "supertest";
describe("RegistrationController", () => {
describe("registration", () => {
const app = express();
it("If an error occurs during the execution of the method, the next('Houston, we have a problem') call should occur", async () => {
const next = jest.fn();
try {
// Passing an empty request to the application that will not pass validation
await request(app).post("/registration");
} catch (e) {
// We compare the result of processing the request by the controller with the expected result
expect(next).toHaveBeenCalledWith("Houston, we have a problem");
}
});
});
});
We are glad that everything works for us
If you know how to properly monitor the "ValidationResult" method from the "express-validator" package . in order not to get errors, please share your way. I have not found such a method on the Internet, I will be very grateful to you
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论