使用 Busted 单元测试 Lua 代码时模拟本地导入
2018-1-23 20:7:39
收藏:0
阅读:94
评论:1
我很新手使用 Lua,我正在尝试测试我正在运行的一个带有 Nginx 服务器的脚本。我被推荐使用 Busted,但我似乎无法弄清楚如何模拟一些本地导入。
Lua 代码导入以下内容:
local http = require "resty.http"
在测试 _spec 文件中,我这样开始:
package.path = "files/?.lua;spec/?.lua;" .. package.path
_G.http = require('resty.fake_http')
local app = require('app')
我在 spec/resty/http 中创建了一个 fake_http.lua 文件。
但是当我运行一个虚拟测试时,我会收到以下错误消息:
suite spec/app_spec.lua
files/app.lua:3: module 'resty.http' not found:No LuaRocks module found for resty.http
这里我做错了什么呢?
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

有几个小问题阻止你的代码工作:
首先,你不能通过设置一个同名的全局变量来覆盖
http局部变量。局部变量将始终遮盖全局变量。其次,
require仍然被调用,如果你在测试代码中删除了local,它仍然会覆盖全局http变量中保存的内容。你需要的是一种方法让
require在被调用时加载你的resty.fake_http模块。我可以想到三种方法:1. 预加载模块
require函数使用两个表package.loaded和package.preload来控制模块的加载时间和方式(详细信息在此)。 当require被调用时,它首先检查package.loaded[module]是否设置,并且如果设置了,返回该值。这是模拟模块的第一个机会:
package.loaded["resty.http"] = require "resty.fake_http" local app = require('app')或者,如果
package.loaded中没有条目,则会检查package.preload[module]是否有可以加载模块的函数:package.preload["resty.http"] = function () return require("resty.fake_http") end local app = require('app')2. 更改package.path并覆盖模块
通过添加
spec目录到路径中,您已经在做这件事。您所需要做的只是将假模块命名为原始模块的名称,它将被自动加载。 例如:test_spec:package.path = "files/?.lua;spec/?.lua;" .. package.path local app = require('app')在测试的代码中,它将自动选择
spec/resty/http.lua。这两种解决方案之间的区别在于,第二种方案只有在测试的代码实际上需要它时,才会**仅导入
resty.fake_http**,而第一种方案则总是需要它。3. Monkeypatch
require这是三种解决方案中最丑陋的一个,但它也可以完美运行。
require只是另一个全局变量,因此你也可以覆盖它:local _original_require = require function require(modname, ...) if modname == "resty.http" then -- implement the exception here return _original_require("resty.fake_http") end -- otherewise act as normal return _original_require(modname, ...) end local app = require('app')第二种方法是最简单实用的,但第一种方法更加清晰和多功能。如果你可以花费30分钟阅读链接文档并了解
require函数的工作原理,那么它可以帮助你解决未来更复杂的问题。