使用 package.preload 模拟 Lua 模块



我正在尝试针对单个模块函数编写单元测试。 此模块与其他一些模块协作,因此我想模拟这些模块以隔离我正在测试的系统。 下面是一些简化的伪代码:

local moduleFoo={}
local moduleBaz=  require("moduleBaz") 
moduleFoo.doSomething = function (arg) 
  if moduleBaz.bar.neatMethod(arg) then
     --does something interesting  
  end
end
return moduleFoo

这是模块Baz的代码

local moduleBaz={}
moduleBaz.bar= {}
moduleBaz.bar.neatMethod=function(arg)
   --does something neat
end
return moduleBaz

我正在尝试使用 package.preload 函数在我的测试运行之前注入 moduleBaz 的模拟实例,但它似乎不起作用(即 moduleBaz 的真实实例用于测试,而不是我的模拟)

下面是一些 psueudo 测试代码:

    package.loaded.moduleBaz= nil
    local moduleBaz = {}
    moduleBaz.bar = {}
    moduleBaz.bar.neatMethod= function(guid) return true end
    package.preload['moduleBaz'] = function ()
        return moduleBaz
    end
   local foo= require("moduleFoo")
   foo.doSomething('asdasdasda')--real moduleBaz is called, not my mock!

知道我做错了什么吗? 我对 Lua 很陌生,对语言中处理范围的方式一点也不满意!

您的模块Baz代码中似乎缺少返回语句

return moduleBaz

为什么不使用package.loaded因为它为您提供了更简单的界面? package.loaded.moduleBaz只需要包含您想要从moduleBaz代码返回的任何内容。像这样的东西应该有效或给你一个想法:

package.loaded.moduleBaz = {
  bar = {
    neatmethod = function(arg)
      -- your mock code here
    end,
  }
}

然后require('moduleBaz')将简单地返回您刚刚创建的对象。

我也无法重现您的设置问题。我使用的文件如下;请注意,我如上所述添加了return moduleBaz,但这是我所做的唯一更改:

文件moduleBaz.lua

local moduleBaz={}
moduleBaz.bar= {}
moduleBaz.bar.neatMethod=function(arg)
  print "baz"
  return true
end
return moduleBaz

文件moduleFoo.lua

local moduleFoo={}
local moduleBaz=  require("moduleBaz") 
  moduleFoo.doSomething = function (arg) 
  if moduleBaz.bar.neatMethod(arg) then
    print "foo"
  end
end
return moduleFoo

文件testFoo.lua

package.loaded.moduleBaz= nil
local moduleBaz = {}
moduleBaz.bar = {}
moduleBaz.bar.neatMethod= function(guid) print "mock" return true end
package.preload['moduleBaz'] = function ()
    return moduleBaz
end
local foo= require("moduleFoo")
foo.doSomething('asdasdasda')--real moduleBaz is called, not my mock!

当我运行它时,我按预期打印mocknfoon

最新更新