3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ユニークビジョン株式会社Advent Calendar 2023

Day 13

Lua でモンキーパッチ

Last updated at Posted at 2023-12-12

以下のような 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 が利用できない環境でテストするときなどに便利そうです。

(モンキーパッチは予期せぬ副作用やバグを引き起こす可能性があるため、このようなコードは本番環境では使用しないほうがよさそうです。)

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?