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.
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})