You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让非面向对象的Lua模块支持依赖注入与单元测试?

解决Lua非面向对象模块的依赖注入与测试问题

好问题!要在保持非OO模块单例特性的同时实现依赖注入(DI)用于测试,我们可以给模块添加一个可配置依赖的入口方法,既不用把模块改成类,也能保留原有的单加载优势。

核心思路

模块默认加载真实的业务依赖,但额外提供一个仅用于测试的方法,允许替换内部的依赖实例;测试完成后还可以重置回默认依赖,避免影响其他测试场景。

具体实现代码

-- 模块默认加载真实的database依赖
local database = require 'database'

local M = {}

function M:GetData()
    return database:GetData()
end

-- 新增:用于测试时注入依赖的方法
function M:InjectDependency(newDatabase)
    database = newDatabase
end

-- 可选:重置回默认依赖,方便测试用例隔离
function M:ResetDependency()
    database = require 'database'
end

return M

方案优势

  • 保持原有使用体验:平时业务代码中调用require后,模块依然是单例,和原来的非OO写法完全一致,没有额外性能开销
  • 支持测试场景:测试时只需调用InjectDependency传入伪造的fake database,就能验证模块的逻辑是否正确调用了依赖的方法
  • 避免重复创建模块实例:不像你之前尝试的闭包方案,每次调用都会生成新的模块副本,这个方案全程复用同一个模块实例

测试场景示例

-- 测试用例代码
local myModule = require 'myModule'

-- 构造伪造的database
local fakeDatabase = {
    GetData = function()
        return "mock test data"
    end
}

-- 注入假依赖
myModule:InjectDependency(fakeDatabase)
-- 验证模块逻辑
assert(myModule:GetData() == "mock test data")

-- 测试完成后重置依赖,避免影响其他用例
myModule:ResetDependency()

这个方案完美平衡了非OO模块的简洁性、单例特性,同时满足了测试阶段的依赖注入需求,不需要对原有模块结构做大幅改动。

内容的提问来源于stack exchange,提问作者Chris Tanner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:18:18