mgyk
@mgyk

Как использовать stub/mock в lua (busted)?

function processEvent(e)
  eventId = getEventType(e)
  if eventId == 3 then
    return 3
  else
    return 0
  end
end


Хочу перекрыть вызов getEventType
package.path = "../?.lua;" .. package.path
describe("processEvent", function()
  it("EventId==3", function()  
    function getEventType() return 3 end
    chunk = assert(loadfile("templates/sr.lua"))
    chunk()
    assert.are.equal(processEvent('hello'), 3)
  end)
end)


Не совсем понятно как правильно загружать код из другого фаила, если код не завернут в модуль. Как не модифицируя исходник перехватить вызов функции getEventType() и вернуть нужное мне значение?
  • Вопрос задан
  • 424 просмотра
Пригласить эксперта
Ответы на вопрос 1
starius
@starius
программист, аспирант МГУ
Попробовал протестировать как-то так с использованием stub:

it("calls getEventType with the event", function()
    function getEventType()
      return 3
    end
    stub(_G, "getEventType")
    processEvent(42)
    assert.stub(getEventType).was.called_with(42)
    getEventType:revert()
  end)


Не работает, хотя должно бы, исходя из документации. Написал об этом разработчикам.

В итоге протестировал всё без spy, mock и stub. На мой взгляд, если отслеживаемых функций не безумное множество, то лучше по-простому.

Не совсем понятно как правильно загружать код из другого фаила, если код не завернут в модуль.
Используйте функцию dofile. Но лучше делать из тестируемых файлов модули и загружать при помощи require.

Замечание по коду: не злоупотребляйте глобальными переменными.

UPD. В busted ответили, что из-за того busted применяет песочницу для тестов, глобальные переменные имеют область видимости в рамках текущего spec-файла или describe-блока. Предложили, как всё-таки протестировать функцию processEvent (присваивать к полям _G), но это потребовало изменять её код. Мораль такова: не пользуйтесь глобальными переменными.

UPD 2. Советуют объявить глобальные функции в отдельном модуле, который подключать через require в тестах. Тогда глобальные переменные попадут в _G тестов и всё будет работать, как ожидалось. Пример кода взят из ответа:

-- processEvent.lua
function getEventType(e)
  ...
end

function processEvent(e)
  eventId = getEventType(e)
  if eventId == 3 then
    return 3
  else
    return 0
  end
end

-- process_event_spec.lua
require 'processEvent'

describe("processEvent", function()
  it("calls getEventType with the event", function()
    stub(_G, "getEventType")
    processEvent(42)
    assert.stub(getEventType).was.called_with(42)
    getEventType:revert()
  end)
end)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы