用Lua进行猴子补丁
我有一个访问Redis的Lua程序,希望测试它的运行情况。
local function main()
local redis = require('redis')
-- Redis に接続
local client = redis.connect('redis://localhost:6379/0')
-- 値を set する
client:set('test_key', 'test_value')
-- 値を get する
local result = client:get('test_key')
return result
end
return main
在Redis未启动的开发环境中,我们尝试通过下面的测试程序(test1.lua)来调用上述函数。
local function test()
local main = require('main')
print(main())
end
test()
执行时发生了如下错误。
似乎在redis.connect函数中无法连接到Redis出现了错误。
$ lua test1.lua
lua: /usr/local/share/lua/5.3/redis.lua:764: could not connect to localhost:6379 [closed]
stack traceback:
[C]: in function 'error'
/usr/local/share/lua/5.3/redis.lua:802: in function 'redis.error'
/usr/local/share/lua/5.3/redis.lua:764: in function </usr/local/share/lua/5.3/redis.lua:760>
(...tail calls...)
/usr/local/share/lua/5.3/redis.lua:836: in function 'redis.connect'
./main.lua:4: in function 'main'
test1.lua:3: in local 'test'
test1.lua:5: in main chunk
[C]: in ?
我已经将这个程序做出以下的修改。
local function test()
local redis = require('redis')
-- redis.connect 関数をオーバーライドして、Redis に接続しないように変更
redis.connect = function()
return {
-- set したときの動作を定義
set = function(self, key, value)
print(string.format('[debug] set called (key: %s, value: %s)', key, value))
end,
-- get したときの動作を定義
get = function(self, key)
print(string.format('[debug] get called (key: %s)', key))
return 'injected value'
end,
}
end
local main = require('main')
print(main())
end
test()
这个程序可以在不启动 Redis 的情况下运行。
$ lua test2.lua
[debug] set called (key: test_key, value: test_value)
[debug] get called (key: test_key)
injected value
在Redis不可用的环境中进行测试时,这种方法似乎很方便。
使用Monkey Patch代码在生产环境中可能会引发意外的副作用和错误,因此最好不要在正式环境中使用这样的代码。