Skip to content

Commit 21eab1d

Browse files
committed
Support for mocking callable tables in objects and tables
1 parent 5d98fa8 commit 21eab1d

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

mock.lua

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,18 @@ function Mock:mockMethod(name)
159159
return m
160160
end
161161

162+
function IsCallable(x)
163+
local isFunction = type(x) == 'function'
164+
local hasCallMetamethod = type((debug.getmetatable(x) or {}).__call) == 'function'
165+
return isFunction or hasCallMetamethod
166+
end
167+
162168
function Mock:mockTable(t, name)
163169
name = name or '<anonymous>'
164170
local mocked = {}
165171

166172
for k, v in pairs(t) do
167-
if type(v) == 'function' then
173+
if IsCallable(v) then
168174
mocked[k] = self:mockFunction(name .. '.' .. tostring(k))
169175
end
170176
end
@@ -177,7 +183,7 @@ function Mock:mockObject(o, name)
177183
local mocked = {}
178184

179185
for k, v in pairs(o) do
180-
if type(v) == 'function' then
186+
if IsCallable(v) then
181187
mocked[k] = self:mockMethod(name .. ':' .. tostring(k))
182188
end
183189
end

spec/mock_spec.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,32 @@ describe('The mock library', function()
194194
end)
195195
end)
196196

197+
it('should allow mocking of any callable in an object, not just functions', function()
198+
local someTable = {
199+
foo = {}
200+
}
201+
202+
setmetatable(someTable.foo, {__call = function() end})
203+
204+
local mockedTable = mock:mockTable(someTable)
205+
206+
mock(mockedTable.foo):shouldBeCalled():
207+
when(function() mockedTable.foo() end)
208+
end)
209+
210+
it('should allow mocking of any callable in a table, not just functions', function()
211+
local someObject = {
212+
foo = {}
213+
}
214+
215+
setmetatable(someObject.foo, {__call = function() end})
216+
217+
local mockedObject = mock:mockObject(someObject)
218+
219+
mock(mockedObject.foo):shouldBeCalled():
220+
when(function() mockedObject:foo() end)
221+
end)
222+
197223
it('should fail when a method is incorrectly used as a function', function()
198224
shouldFail(function()
199225
local someObject = {}

0 commit comments

Comments
 (0)