用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代码在生产环境中可能会引发意外的副作用和错误,因此最好不要在正式环境中使用这样的代码。

广告
将在 10 秒后关闭
bannerAds