Модульное тестирование локальной функции в 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})
Другие вопросы по тегам