重置 Lua 测试后的 package.loaded

我正在 Lua 中开发单元测试,并且更改 package.loaded 是这些测试的一部分。这从以下代码开始

a = require "parser"
a.b = nil

package.loaded["checker"] = function() return true end

当我修改了测试开始前已经加载的 package.loaded 条目时,情况就变得很复杂。

我想在每个测试后重置 package.loaded。但我很难实现。我尝试过包装 require,这解决了一些问题,但无法解决第二个和第三个示例的问题。我该如何在测试开始前正确地创建 package.loaded 的保存点,并在开始新测试前重新加载该保存点?或者将 package.loaded 回滚到解释器启动后的状态?

点赞
用户1216152
用户1216152

对我来说,只要浅复制 package.loaded_G 就足够了。可以在这里找到浅复制函数:http://lua-users.org/wiki/CopyTable

function shallowcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in pairs(orig) do
            copy[orig_key] = orig_value
        end
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

实际测试如下:

local packageLoadedCopy = shallowcopy(package.loaded)
local gCopy = shallowcopy(_G)
for _, test in ipairs(tests) do
    -- 做出实际的测试
    -- 清理环境
    local markDeletion = {}
    local markModify = {}
    for name in pairs(package.loaded) do
        if not packageLoadedCopy[name] then
            table.insert(markDeletion, name)
        elseif packageLoadedCopy[name] ~= package.loaded[name] then
            table.insert(markModify, name)
        end
    end
    for _, name in pairs(markDeletion) do
        package.loaded[name] = nil
    end
    for _, name in pairs(markModify) do
        package.loaded[name] = packageLoadedCopy[name]
    end
    markDeletion, markModify = {}, {}
    for name in pairs(_G) do
        if not gCopy[name] then
            table.insert(markDeletion, name)
        elseif _G[name] ~= gCopy[name] then
            table.insert(markModify, name)
        end
    end
    for _, name in pairs(markDeletion) do
        _G[name] = nil
    end
    for _, name in pairs(markModify) do
        _G[name] = gCopy[name]
    end
end

请注意,简单地

package.loaded = packageLoadedCopy
_G = gCopy

不起作用,我不确定为什么。

2020-05-25 08:19:56