lunarmodules / luassert

Assertion library for Lua
MIT License
202 stars 76 forks source link

How to make spy (or mock or stub) not change function type? #173

Closed NickFlexer closed 3 years ago

NickFlexer commented 3 years ago

Hi!

When wrapping a function in Spy, the type of the resulting entity changes to table. Is it possible to preserve the original type of function when using Spy? Same behavior when using Mock or Stub

example:

local t = {
    some = function () return 42 end
}

local m = mock(t)

assert.is.Function(m.some) -- raise 'type different types'
DorianGray commented 3 years ago

would using assert.is.callable be acceptable? Otherwise, would you mind detailing the use case?

NickFlexer commented 3 years ago

I am testing a function that will check the type of the parameter passed to it. If I change the function to stub, then I get a false error in the test:

function test_function(a)
    if type(a) ~= "function" then
        error("argument is not a function!")
    else
        a(10)
    end
end

it("check function call", function ()
    local s = spy.new(function () end)

    test_function(s) -- raise error!

    assert.spy(s).was.called(1)
    assert.spy(s).was.called_with(10)
end)

I think it is possible to change the check in the function to type(a) ~= "function" and type(a) ~= "table". But is there a way to leave Spy as a function?

Tieske commented 3 years ago

try this:

function test_function(a)
    if type(a) ~= "function" then
        error("argument is not a function!")
    else
        a(10)
    end
end

function spy_as_function(s)
    return s, function(...) return s(...) end
end

it("check function call", function ()
    local s, sf = spy_as_function(spy.new(function () end))

    test_function(sf) -- raise error!

    assert.spy(s).was.called(1)
    assert.spy(s).was.called_with(10)
end)
NickFlexer commented 3 years ago

@Tieske Thank you, it works!

I think, the issue can be closed