Skip to content

Instantly share code, notes, and snippets.

@kurapica
Created February 8, 2023 06:18
Show Gist options
  • Save kurapica/7cf53c2d468e70685b61cf6b817c2bb0 to your computer and use it in GitHub Desktop.
Save kurapica/7cf53c2d468e70685b61cf6b817c2bb0 to your computer and use it in GitHub Desktop.
The Interceptor used for unit test, replace the global api in modules
require "PLoop"
require "PLoop.System.UnitTest"
-- Function defintion in _G
function UnitName()
return "player"
end
-- Define an interceptor
PLoop(function(_ENV)
System.Logger.Default:AddHandler(print)
-- The Access Interceptor
class "TestNS.AccessInterceptor" (function(_ENV)
local _interceptor = Toolset.newtable(true)
local function resetModule(module, parent, cache)
if cache[module] then return end
cache[module] = true
for k, v in pairs(module) do
if type(v) == "function" and rawget(parent, k) == v then
-- Clear module cache
rawset(module, k, nil)
elseif Class.Validate(v) then
-- Clear class defintion environment cache
for name, func in Class.GetMethods(v) do
resetModule(getfenv(func), parent, cache)
break
end
elseif Interface.Validate(v) then
-- Clear interface defintion environment cache
for name, func in Interface.GetMethods(v) do
resetModule(getfenv(func), parent, cache)
break
end
elseif Struct.Validate(v) then
-- Clear struct defintion environment cache
for name, func in Struct.GetMethods(v) do
resetModule(getfenv(func), parent, cache)
break
end
end
end
if module.GetModules then
for _, m in module:GetModules() do
resetModule(m, parent, cache)
end
end
end
-- Install the interceptor into module
__Arguments__{ Module }
function InstallModule(self, module)
resetModule(module, _G, {})
for k, v in pairs(_interceptor[self]) do
rawset(module, k, v)
end
end
-- UnInstall the interceptor from the module
__Arguments__{ Module }
function UnInstallModule(self, module)
resetModule(module, _interceptor[self], {})
end
__Arguments__{ Table }
function __ctor(self, table)
_interceptor[self] = table
end
end)
Module "TestModule" (function(_ENV)
namespace "TestNS"
class "A" (function(_ENV)
function GetUnitName()
return UnitName()
end
end)
end)
-- Declare the unit test for Test Module
UnitTest "Test.Example" (function(_ENV)
-- Prepare the interceptor
interceptor = TestNS.AccessInterceptor{
UnitName = function()
return "target"
end
}
function OnInit(self)
-- Install the interceptor
interceptor:InstallModule(Module("TestModule"))
end
function OnFinal(self)
-- UnInstall the interceptor
interceptor:UnInstallModule(Module("TestModule"))
end
__Test__() function test1()
local object = TestNS.A()
Assert.Equal("target", object:GetUnitName())
end
end)
print("Before UnitTest", TestNS.A():GetUnitName())
UnitTest("Test"):Run()
print("After UnitTest", TestNS.A():GetUnitName())
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment