使用busted测试lua脚本

我正在尝试使用busted测试我们的Freeswitch lua脚本,但却遇到了麻烦。问题的要点是,我需要能够窥探方程式,例如以下内容:

local req_host = session:getVariable('sip_req_host')
session:setVariable('curl_timeout', 0)

但我似乎无法弄清楚如何构建应该将_G.session设置为的对象。我能找到的最好/唯一好的busted使用示例位于https://github.com/chris-allnutt/unit-tested-corona/blob/master/mocks/button.lua ,但它似乎使用相同的简单语法来构建模拟对象,busted文档也是如此。

local button = {
  x = 0,
  y = 0,
  addEventListener = function() end
}

我可以看出,这对于不需要返回任何东西的简单函数是有效的,但我需要能够使用getVariable和setVariable函数从会话对象中获取和设置变量。我的简单模拟对象如下:

Session = {}
Session.__index = Session

function Session.create(params)
  local session = {}
  setmetatable(session, Session)
  session.params = params
  return session
end

function Session:getVariable(key)
  return self.params[key]
end

function Session:setVariable(key, val)
  self.params[key] = val
end

function Session:execute(cmd, code)
end

测试如下:

require "busted"
require("test_utils")

describe("Test voip lua script", function()
  it('Test webrtc bad domain', function()
    domain = 'rtc.baddomain.com';
    session_params = {['sip_req_host'] = domain,
                      ['sip_req_user'] = 'TEST-WebRTC-Client',
                      ["sip_from_user"] = 'testwebrtc_p_12345',
                      ['sip_call_id'] = 'test@call_id',
                      ['sip_authorized'] = 'false'}
    exec_str = 'sofia_contact TEST-WebRTC-Client@'..domain;
    api_params = {[exec_str] = 'error/user_not_registered'}

    _G.session = mock(Session.create(session_params), 'execute')
    _G.api = API.create(api_params)
    _G.freeswitch = Freeswitch.create()

    dofile("tested_script.lua")

    assert.spy(_G.session.execute).called_with("respond", "407")
  end)
end)

我得到以下异常。 /usr/local/share/lua/5.2/luassert/spy.lua:78: attempt to index a function value

这个异常被luassert抛出,luassert是busted库的一个依赖项,在以下if语句中

77:local function called_with(state, arguments)
78:  if rawget(state, "payload") and rawget(state, "payload").called_with then
79:    return state.payload:called_with(arguments)
80:  else
81:    error("'called_with' must be chained after 'spy(aspy)'")
82:  end
83:end

我对lua的了解很少,因此很可能我只是错过了语言中的一些明显部分,但任何帮助或指针都将不胜感激。

点赞
用户1461066
用户1461066

mod_lua 在 FreeSWITCH 中使用了一个稍微定制的 Lua 解释器,而您似乎使用了在您主机上安装的不同的 Lua 解释器。我猜它们不会轻易地一起工作。

2014-04-30 10:59:05
用户3587406
用户3587406

经过一天的调试,我发现答案是:是的,你需要使用一个表作为你调用mock的对象。然而,由于Lua是一种非常宽容的语言,当涉及到使用可调用参数构建对象时,这仍然可以工作。我已经为与本问题无关的原因构建了一个对象包装器,但你可以看到我的最终工作代码如下。

function SessionConstructor.create(params)
  local session_constructor = {}
  setmetatable(session_constructor, SessionConstructor)
  session_constructor.session = {}
  session_constructor.session.params = params
  session_constructor.session.getVariable = function(self,key)
    return self.params[key]
  end
  session_constructor.session.setVariable = function(self, key, val)
    self.params[key] = val
  end
  session_constructor.session.execute = function(self, cmd, code)
  end

  return session_constructor
end

function SessionConstructor:construct()
  return self.session
end

还有一项重要的说明,因为你必须将self传入使用lua的“:”语法调用的函数中,所以用于监视哪些函数被调用的方法确实会发生改变,如下面的测试文件所示。

require "busted"
require "test_utils"

describe("Test voip lua script", function()
  it('Test webrtc bad domain', function()
    domain = 'rtc.baddomain.com';
    session_params = {['sip_req_host'] = domain,
                      ['sip_req_user'] = 'TEST-WebRTC-Client',
                      ["sip_from_user"] = 'testwebrtc_p_12345',
                      ['sip_call_id'] = 'test@call_id',
                      ['sip_authorized'] = 'false'}
    local sess_con = SessionConstructor.create(session_params)

    exec_str = 'sofia_contact TEST-WebRTC-Client@'..domain;
    local api_con = APIConstructor.create()
    api_con:expect_exec(exec_str, 'error/user_not_registered')

    _G.session = mock(sess_con:construct())
    _G.api = mock(api_con:construct())
    _G.freeswitch = create_freeswitch()

    dofile("tested_script.lua")

    assert.spy(session.execute).was.called_with(session, "respond", "407")
    assert.spy(session.execute).was_not.called_with("respond", "407") --这很不幸
  end)
end)
2014-04-30 22:06:32