lunarmodules / luassert

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

Type introspection on spies? #159

Closed andweeb closed 5 years ago

andweeb commented 5 years ago

It doesn't seem like it's possible to test code that branches on a condition like type(x) == "function".

For example, the snippet below tests a function example that branches on that condition:

local function example(arg)
    if type(arg) == "function" then
        return arg()
    end
end

describe("example", function()
    it("should handle function arguments", function()
        local spy = spy.new(function() end)

        example(spy)

        assert.spy(spy).was.called()
    end)
end)

Since the type() of a spy is actually "table", the test fails with the following output on the spy assertion:

Failure → spec/example_spec.lua @ 8
example should handle function arguments
spec/example_spec.lua:12: Expected to be called >0 time(s), but was called 0 time(s)

Attempts to mock the global type function to "correctly" return "function" on spied functions also fail with the validation error thrown here.

Is there a way to bypass the validation error, or is there a better way to go about testing the example function?

Tieske commented 5 years ago

It's a bit tricky to fix, but the workaround is simple, just wrap the spy in another function:

local function example(arg)
    if type(arg) == "function" then
        return arg()
    end
end

describe("example", function()
    it("should handle function arguments", function()
        local spy = spy.new(function() end)
        local wspy = function(...) return spy(...) end         -- added

        example(wspy)                                          -- call on 'wspy' now

        assert.spy(spy).was.called()
    end)
end)

please close if this is satisfactory

andweeb commented 5 years ago

Ah I see. Yeah that workaround is fine, thanks! I'll close this.