以下のような 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 が利用できない環境でテストするときなどに便利そうです。
(モンキーパッチは予期せぬ副作用やバグを引き起こす可能性があるため、このようなコードは本番環境では使用しないほうがよさそうです。)