Dependency injection 如何在没有OO的情况下对Lua模块进行单元测试?
在Lua中,我可以编写这样一个简单的模块Dependency injection 如何在没有OO的情况下对Lua模块进行单元测试?,dependency-injection,lua,functional-programming,Dependency Injection,Lua,Functional Programming,在Lua中,我可以编写这样一个简单的模块 local database = require 'database' local M = {} function M:GetData() return database:GetData() end return M 当需要时,将加载一次,所有未来版本将加载同一副本 如果我想采用面向对象的方法,我可以做如下事情: local M = {} M.__index = M function M:GetData() return sel
local database = require 'database'
local M = {}
function M:GetData()
return database:GetData()
end
return M
当需要时,将加载一次,所有未来版本将加载同一副本
如果我想采用面向对象的方法,我可以做如下事情:
local M = {}
M.__index = M
function M:GetData()
return self.database:GetData()
end
return function(database)
local newM = setmetatable({}, M)
newM.database = database
return newM
end
其中M只加载一次,newM的每个副本只保存自己的数据并使用原始M的方法
当涉及到测试时,使用OO方法,我可以传入一个假的“数据库”版本并检查它是否被调用,但使用第一种方法,我不能
因此,我的问题是,如何使第一种方法支持DI/测试,而不使其像类一样
我的想法是把它包装成这样一个结尾:
local mClosure = function(database)
local M = {}
function M:GetData()
return database:GetData()
end
return M
end
return mClosure
但是,每次调用它都会创建一个新的M副本,因此它将失去前面两种方法的优点。这显然是Lua的一个用例。这样,您就可以修改函数的upvalue并注入依赖项。也可以考虑使用<代码>要求< /代码>;只需请求一次数据库模块,创建一个收集数据的小表,然后重定向到原始模块并将其放入
包中。加载以便下次请求它时,require
调用返回模块的修改版本。OO方法是在Ruby这样的语言中实现这类功能的方法,但在Lua中,我们有更好的方法来利用模块或函数,而不是专门为此目的而设计的
local real_db = require 'db'
local fake_db = setmetatable({}, {__index=db})
function fake_db.exec(query) print('running query: '..query) end -- dummy function
function fake_db.something(...) print('doing something'); real_db.something(...) end
package.loaded.db = fake_db
require 'my_tests' -- this in turn requires 'db', but gets the fake one
package.loaded.db = real_db
-- After this point, `require 'db'` will return the original module
我不确定我是否理解你的问题。但是你可以临时用假的来替换moduledatabase.lua
,只是为了测试。如果不碰正在测试的代码,我该怎么做呢?