Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing local function in Lua

So I'm using Busted to create unit tests for an existing Lua file, without changing the code in the file if possible. The file imports another file, and then stores various methods from that file in local functions, like so.

[examplefile.lua]
local helper = require "helper.lua"
local helper_accept = helper.accept
local helper_reject = helper.reject

foo = new function()
  -- do something which uses helper_accept
  -- do something which uses helper_reject
end

I want to spy on these methods in my tests to ensure that they have been called at the right places. However, I can't find any way to do this from the test. I've tried simply mocking out the helper methods, as in:

[exampletest.lua]

local helper = require "helper.lua"
local examplefile = require "examplefile.lua"

-- mock the helper function to simply return true
helper.accept = new function() return true end
spy.on(helper, "accept")
examplefile:foo
assert.spy(helper).was().called()

but that doesn't work as the real file uses the helper_accept and helper_reject methods, not helper.accept and helper.reject.

Can this be done without changing the code? Thanks.

like image 568
Ryan Avatar asked Oct 30 '25 03:10

Ryan


1 Answers

The easiest way I can think of for accomplishing this is to override the "helper" library with hook stubs. You can do this by modifying the package.loaded table. The package.loaded table stores the result of an initial call to require "lib", so that if the same require is called again, the module does not need to be reloaded. If you place something in there before the first call to require "lib", it will never actually load the library from the filesystem.

In your case you may want to actually load the library, but hook all the library accesses. I'd do that something like this...

local lib = require "lib"

local function hook_func(_, key)
    print('Accessing "lib" attribute '..tostring(key))
    -- other stuff you might want to do in the hook
    return lib[key]
end

package.loaded["lib"] = setmetatable({}, {__index = hook_func})
like image 182
ktb Avatar answered Nov 01 '25 09:11

ktb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!