Skip to content

Commit 0ea96f0

Browse files
committed
Initial support for mock naming
1 parent 9b026a0 commit 0ea96f0

File tree

2 files changed

+81
-73
lines changed

2 files changed

+81
-73
lines changed

mock.lua

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ local Mock = {}
44

55
local subscriber
66

7-
local function unexpectedCall()
8-
error('unexpected Mock function called')
9-
end
10-
117
local function mockHandle(callback, thunk)
128
subscriber = callback
139
thunk()
1410
subscriber = nil
1511
end
1612

17-
local function mockCalled(m, args)
18-
return subscriber(m, args)
13+
local function mockCalled(m, name, args)
14+
return subscriber(m, name, args)
1915
end
2016

2117

@@ -79,11 +75,10 @@ function MockExpectation:andWillReturn(...)
7975
end
8076

8177
function MockExpectation:when(thunk)
82-
local function called(m, args)
78+
local function called(m, name, args)
8379
assert(#self._calls > 0, 'unexpected call')
84-
85-
assert(self._calls[1]:functionMatches(m), 'unexpected function called')
86-
assert(self._calls[1]:argsMatch(args), 'unexpected arguments provided')
80+
assert(self._calls[1]:functionMatches(m), 'unexpected function "' .. name .. '" called', 2)
81+
assert(self._calls[1]:argsMatch(args), 'unexpected arguments provided to function "' .. name .. '"')
8782

8883
return table.remove(self._calls, 1):getReturnValues()
8984
end
@@ -134,46 +129,50 @@ end
134129

135130

136131

137-
function Mock:mockFunction()
132+
function Mock:mockFunction(name)
133+
name = name or '<anonymous>'
138134
local f
139135

140136
function f(...)
141-
return mockCalled(f, table.pack(...))
137+
return mockCalled(f, name, table.pack(...))
142138
end
143139

144140
return f
145141
end
146142

147-
function Mock:mockMethod()
143+
function Mock:mockMethod(name)
144+
name = name or '<anonymous>'
148145
local m
149146

150147
function m(...)
151148
local args = table.pack(...)
152149
table.remove(args, 1)
153-
return mockCalled(m, args)
150+
return mockCalled(m, name, args)
154151
end
155152

156153
return m
157154
end
158155

159-
function Mock:mockTable(t)
156+
function Mock:mockTable(t, name)
157+
name = name or '<anonymous>'
160158
local mocked = {}
161159

162160
for k, v in pairs(t) do
163161
if type(v) == 'function' then
164-
mocked[k] = self:mockFunction()
162+
mocked[k] = self:mockFunction(name .. '.' .. tostring(k))
165163
end
166164
end
167165

168166
return mocked
169167
end
170168

171-
function Mock:mockObject(o)
169+
function Mock:mockObject(o, name)
170+
name = name or '<anonymous>'
172171
local mocked = {}
173172

174173
for k, v in pairs(o) do
175174
if type(v) == 'function' then
176-
mocked[k] = self:mockMethod()
175+
mocked[k] = self:mockMethod(name .. ':' .. tostring(k))
177176
end
178177
end
179178

spec/mock_spec.lua

Lines changed: 64 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,128 +7,139 @@ describe('The mock library', function()
77
end
88
end
99

10+
local function shouldFailWith(expectedMessage, test)
11+
local result, actualMessage = pcall(test)
12+
_, _, actualMessage = actualMessage:find(":%w+: (.+)")
13+
14+
if(result) then
15+
error('expected failure did not occur')
16+
elseif(actualMessage ~= expectedMessage) then
17+
error('expected failure message: "' .. expectedMessage .. '" did not match actual failure message: "' .. actualMessage .. '"')
18+
end
19+
end
20+
1021
it('should allow you to verify that a function is called', function()
11-
local m = mock:mockFunction()
22+
local f = mock:mockFunction('f')
1223

13-
mock(m):shouldBeCalled():
14-
when(function() m() end)
24+
mock(f):shouldBeCalled():
25+
when(function() f() end)
1526
end)
1627

1728
it('should alert you when a function is not called', function()
18-
local m = mock:mockFunction()
29+
local f = mock:mockFunction('f')
1930

2031
shouldFail(function()
21-
mock(m):shouldBeCalled():
32+
mock(f):shouldBeCalled():
2233
when(function() end)
2334
end)
2435
end)
2536

2637
it('should alert you when the wrong function is called', function()
27-
local m1 = mock:mockFunction()
28-
local m2 = mock:mockFunction()
38+
local f1 = mock:mockFunction('f1')
39+
local f2 = mock:mockFunction('f2')
2940

30-
shouldFail(function()
31-
mock(m1):shouldBeCalled():
32-
when(function() m2() end)
41+
shouldFailWith('unexpected function "f2" called', function()
42+
mock(f1):shouldBeCalled():
43+
when(function() f2() end)
3344
end)
3445
end)
3546

3647
it('should alert you when a function is called unexpectedly', function()
37-
local m = mock:mockFunction()
48+
local f = mock:mockFunction('f')
3849

39-
shouldFail(function()
40-
m()
50+
shouldFailWith('unexpected function "f" called', function()
51+
f()
4152
end)
4253
end)
4354

4455
it('should allow you to verify that a function has been called with the correct arguments', function()
45-
local m = mock:mockFunction()
56+
local f = mock:mockFunction('f')
4657

47-
mock(m):shouldBeCalledWith(1, '2'):
48-
when(function() m(1, '2') end)
58+
mock(f):shouldBeCalledWith(1, '2'):
59+
when(function() f(1, '2') end)
4960
end)
5061

5162
it('should alert you when a function has been called with incorrect arguments', function()
52-
local m = mock:mockFunction()
63+
local f = mock:mockFunction('f')
5364

5465
shouldFail(function()
55-
mock(m):shouldBeCalledWith(1, '2'):
56-
when(function() m(1, '3') end)
66+
mock(f):shouldBeCalledWith(1, '2'):
67+
when(function() f(1, '3') end)
5768
end)
5869
end)
5970

6071
it('should allow you to specify the return value of a mocked function', function()
61-
local m = mock:mockFunction()
72+
local f = mock:mockFunction('f')
6273

63-
mock(m):shouldBeCalled():andWillReturn(4):
74+
mock(f):shouldBeCalled():andWillReturn(4):
6475
when(function()
65-
assert.is.equal(m(), 4)
76+
assert.is.equal(f(), 4)
6677
end)
6778
end)
6879

6980
it('should allow you to specify multiple return values for a mocked function', function()
70-
local m = mock:mockFunction()
81+
local f = mock:mockFunction('f')
7182

72-
mock(m):shouldBeCalled():andWillReturn(1, 2):
83+
mock(f):shouldBeCalled():andWillReturn(1, 2):
7384
when(function()
74-
r1, r2 = m()
85+
r1, r2 = f()
7586
assert.is.equal(r1, 1)
7687
assert.is.equal(r2, 2)
7788
end)
7889
end)
7990

8091
it('should allow you to check that a function has been called multiple times', function()
81-
local m = mock:mockFunction()
92+
local f = mock:mockFunction('f')
8293

83-
mock(m):shouldBeCalled():
84-
andAlso(mock(m):shouldBeCalledWith(1, 2, 3)):
94+
mock(f):shouldBeCalled():
95+
andAlso(mock(f):shouldBeCalledWith(1, 2, 3)):
8596
when(function()
86-
m()
87-
m(1, 2, 3)
97+
f()
98+
f(1, 2, 3)
8899
end)
89100
end)
90101

91102
it('should allow you to check that multiple functions are called', function()
92-
local m1 = mock:mockFunction()
93-
local m2 = mock:mockFunction()
103+
local f1 = mock:mockFunction('f1')
104+
local f2 = mock:mockFunction('f2')
94105

95-
mock(m1):shouldBeCalled():
96-
andAlso(mock(m2):shouldBeCalledWith(1, 2, 3)):
106+
mock(f1):shouldBeCalled():
107+
andAlso(mock(f2):shouldBeCalledWith(1, 2, 3)):
97108
when(function()
98-
m1()
99-
m2(1, 2, 3)
109+
f1()
110+
f2(1, 2, 3)
100111
end)
101112
end)
102113

103114
it('should allow you to mix and match call types', function()
104-
local m1 = mock:mockFunction()
105-
local m2 = mock:mockFunction()
115+
local f1 = mock:mockFunction('f1')
116+
local f2 = mock:mockFunction('f2')
106117

107-
mock(m1):shouldBeCalled():
108-
andAlso(mock(m2):shouldBeCalledWith(1, 2, 3)):
109-
andThen(mock(m2):shouldBeCalledWith(1):andWillReturn(4)):
118+
mock(f1):shouldBeCalled():
119+
andAlso(mock(f2):shouldBeCalledWith(1, 2, 3)):
120+
andThen(mock(f2):shouldBeCalledWith(1):andWillReturn(4)):
110121
when(function()
111-
m1()
112-
m2(1, 2, 3)
113-
assert.is.equal(m2(1), 4)
122+
f1()
123+
f2(1, 2, 3)
124+
assert.is.equal(f2(1), 4)
114125
end)
115126
end)
116127

117128
it('should allow functions to be used to improve readability', function()
118-
local m1 = mock:mockFunction()
119-
local m2 = mock:mockFunction()
129+
local f1 = mock:mockFunction('f1')
130+
local f2 = mock:mockFunction('f1')
120131

121132
function somethingShouldHappen()
122-
return mock(m1):shouldBeCalled()
133+
return mock(f1):shouldBeCalled()
123134
end
124135

125136
function anotherThingShouldHappen()
126-
return mock(m2):shouldBeCalledWith(1, 2, 3)
137+
return mock(f2):shouldBeCalledWith(1, 2, 3)
127138
end
128139

129140
function theCodeUnderTestRuns()
130-
m1()
131-
m2(1, 2, 3)
141+
f1()
142+
f2(1, 2, 3)
132143
end
133144

134145
somethingShouldHappen():
@@ -142,7 +153,7 @@ describe('The mock library', function()
142153
bar = function() end
143154
}
144155

145-
mockedTable = mock:mockTable(someTable)
156+
mockedTable = mock:mockTable(someTable, 'someTable')
146157

147158
mock(mockedTable.foo):shouldBeCalledWith(1):andWillReturn(2):
148159
andAlso(mock(mockedTable.bar):shouldBeCalled()):
@@ -199,7 +210,7 @@ describe('The mock library', function()
199210
end)
200211

201212
it('should let you expect a function to be called multiple times', function()
202-
local f = mock:mockFunction()
213+
local f = mock:mockFunction('f')
203214

204215
mock(f):shouldBeCalledWith(2):andWillReturn(1):multipleTimes(3):
205216
when(function()
@@ -223,7 +234,7 @@ describe('The mock library', function()
223234

224235
it('should fail if a function is called too many times', function()
225236
shouldFail(function()
226-
local f = mock:mockFunction()
237+
local f = mock:mockFunction('f')
227238

228239
mock(f):shouldBeCalledWith(2):andWillReturn(1):multipleTimes(2):
229240
when(function()
@@ -236,7 +247,5 @@ describe('The mock library', function()
236247

237248
-- ordering
238249

239-
-- multiple times
240-
241250
-- allowed vs. not allowed functions on the expectation (ie: state machine for expectation)
242251
end)

0 commit comments

Comments
 (0)