Модульное тестирование локальной функции в Lua
Поэтому я использую Busted для создания модульных тестов для существующего файла Lua, без изменения кода в файле, если это возможно. Файл импортирует другой файл, а затем сохраняет различные методы из этого файла в локальных функциях, например, так.
[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
Я хочу следить за этими методами в своих тестах, чтобы убедиться, что они были вызваны в нужных местах. Тем не менее, я не могу найти способ сделать это из теста. Я попытался просто макет вспомогательных методов, как в:
[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()
но это не работает, поскольку настоящий файл использует методы helper_accept и helper_reject, а не helper.accept и helper.reject.
Можно ли это сделать без изменения кода? Благодарю.
1 ответ
Самый простой способ, который я могу придумать для достижения этой цели, - переопределить библиотеку "помощника" с помощью заглушек. Вы можете сделать это, изменив package.loaded
Таблица. package.loaded
таблица хранит результат начального вызова require "lib"
, чтобы при повторном вызове того же запроса модуль не нужно было перезагружать. Если вы поместите что-то там до первого звонка require "lib"
, он никогда не загрузит библиотеку из файловой системы.
В вашем случае вы можете загрузить библиотеку, но перехватить все обращения к библиотеке. Я бы сделал это примерно так...
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})