Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependency injection 如何在没有OO的情况下对Lua模块进行单元测试?_Dependency Injection_Lua_Functional Programming - Fatal编程技术网

Dependency injection 如何在没有OO的情况下对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

在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 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

我不确定我是否理解你的问题。但是你可以临时用假的来替换module
database.lua
,只是为了测试。如果不碰正在测试的代码,我该怎么做呢?