使用package.preload模拟lua模块

Mit*_*h A 4 lua mocking

我正在尝试针对单个模块函数编写单元测试.这个模块与其他几个模块合作,所以我想模拟那些模块来隔离我测试的系统.这是一些简化的伪代码:

local moduleFoo={}
local moduleBaz=  require("moduleBaz") 

moduleFoo.doSomething = function (arg) 

  if moduleBaz.bar.neatMethod(arg) then
     --does something interesting  
  end

end

return moduleFoo
Run Code Online (Sandbox Code Playgroud)

这是moduleBaz的代码

local moduleBaz={}
moduleBaz.bar= {}

moduleBaz.bar.neatMethod=function(arg)
   --does something neat
end
return moduleBaz
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用package.preload函数在我的测试运行之前注入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!
Run Code Online (Sandbox Code Playgroud)

我有什么想法我做错了吗?我对Lua很新,对语言中的范围处理方式一点也不熟悉!

Pau*_*nko 7

您似乎在moduleBaz代码中缺少return语句

return moduleBaz
Run Code Online (Sandbox Code Playgroud)

为什么不使用package.loaded它,因为它给你一个更简单的界面?package.loaded.moduleBaz只需要包含你想从moduleBaz代码中返回的内容.这样的事情应该起作用或给你一个想法:

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

然后require('moduleBaz')只返回刚刚创建的对象.

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

档案moduleBaz.lua:

local moduleBaz={}
moduleBaz.bar= {}
moduleBaz.bar.neatMethod=function(arg)
  print "baz"
  return true
end
return moduleBaz
Run Code Online (Sandbox Code Playgroud)

档案moduleFoo.lua:

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

文件 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!
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我mock\nfoo\n按预期打印.