Skip to content

Commit fe32e10

Browse files
committed
Add stacked stub support
1 parent 84dbc57 commit fe32e10

File tree

3 files changed

+68
-15
lines changed

3 files changed

+68
-15
lines changed

src/AspectMock/Core/Mocker.php

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,32 +140,43 @@ protected function stub(MethodInvocation $invocation, $params)
140140
{
141141
$name = $invocation->getMethod();
142142

143-
$replacedMethod = $params[$name];
144-
145-
$replacedMethod = $this->turnToClosure($replacedMethod);
146-
147-
if ($invocation->isStatic()) {
148-
$replacedMethod = \Closure::bind($replacedMethod, null, $invocation->getThis());
149-
} else {
150-
$replacedMethod = $replacedMethod->bindTo($invocation->getThis(), get_class($invocation->getThis()));
151-
}
152-
return call_user_func_array($replacedMethod, $invocation->getArguments());
143+
return $this->stubIteratively($name, $params, $invocation);
153144
}
154145

155146
protected function stubMagicMethod(MethodInvocation $invocation, $params)
156147
{
157148
$args = $invocation->getArguments();
158149
$name = array_shift($args);
159150

160-
$replacedMethod = $params[$name];
151+
return $this->stubIteratively($name, $params, $invocation);
152+
}
153+
154+
protected function stubIteratively($name, $params, MethodInvocation $invocation)
155+
{
156+
$replacedMethods = $params[$name];
157+
158+
if (!is_array($replacedMethods)) $replacedMethods = [$replacedMethods];
159+
160+
$result = __AM_CONTINUE__;
161+
162+
while ($result === __AM_CONTINUE__ && count($replacedMethods) > 0) {
163+
$replacedMethod = array_pop($replacedMethods);
164+
$result = $this->doStub($invocation, $replacedMethod);
165+
}
166+
167+
return $result;
168+
}
169+
170+
protected function doStub(MethodInvocation $invocation, $replacedMethod)
171+
{
161172
$replacedMethod = $this->turnToClosure($replacedMethod);
162173

163174
if ($invocation->isStatic()) {
164-
\Closure::bind($replacedMethod, null, $invocation->getThis());
175+
$replacedMethod = \Closure::bind($replacedMethod, null, $invocation->getThis());
165176
} else {
166177
$replacedMethod = $replacedMethod->bindTo($invocation->getThis(), get_class($invocation->getThis()));
167178
}
168-
return call_user_func_array($replacedMethod, $args);
179+
return call_user_func_array($replacedMethod, $invocation->getArguments());
169180
}
170181

171182

@@ -181,7 +192,7 @@ public function registerClass($class, $params = array())
181192
{
182193
$class = ltrim($class,'\\');
183194
if (isset($this->classMap[$class])) {
184-
$params = array_merge($this->classMap[$class], $params);
195+
$params = array_merge_recursive($this->classMap[$class], $params);
185196
}
186197
$this->methodMap = array_merge($this->methodMap, array_keys($params));
187198
$this->classMap[$class] = $params;
@@ -191,7 +202,7 @@ public function registerObject($object, $params = array())
191202
{
192203
$hash = spl_object_hash($object);
193204
if (isset($this->objectMap[$hash])) {
194-
$params = array_merge($this->objectMap[$hash], $params);
205+
$params = array_merge_recursive($this->objectMap[$hash], $params);
195206
}
196207
$this->objectMap[$hash] = $params;
197208
$this->methodMap = array_merge($this->methodMap, array_keys($params));

src/AspectMock/Test.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ class Test {
8181
* $user = new User(['name' => 'davert']);
8282
* $user->save(); // false
8383
*
84+
* # on conflicted stubs
85+
* test::double('User', ['getGroup' => function () { return $this->group; }]);
86+
* $user = new User;
87+
* $user->group = 'guest';
88+
* $user->getGroup(); // => guest
89+
* test::double('User', ['getGroup' => function ($supersede = false) { return $supersede ? 'root' : __AM_CONTINUE__; }]);
90+
* $user->group = 'user';
91+
* $user->getGroup(true); // => root
92+
* $user->getGroup(); // => user
93+
*
8494
* ?>
8595
* ```
8696
*

tests/unit/StubTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,45 @@ public function testBindSelfCallback()
4242
$this->assertEquals('awesome', $topSecret);
4343
}
4444

45+
public function testStackedStub()
46+
{
47+
double::registerClass(\demo\UserModel::class, ['getName' => function () {
48+
return 'tsui';
49+
}]);
50+
double::registerClass(\demo\UserModel::class, ['getName' => function () {
51+
return 'tt';
52+
}]);
53+
double::registerClass(\demo\UserModel::class, ['getName' => function () {
54+
return __AM_CONTINUE__;
55+
}]);
56+
$user = new AdminUserModel(['name' => 'torreytsui']);
57+
$name = $user->getName();
58+
$this->assertEquals('tt', $name);
59+
}
60+
4561
public function testObjectInstance()
4662
{
4763
$user = new UserModel(['name' => 'davert']);
4864
double::registerObject($user,['save' => null]);
4965
$user->save();
5066
}
5167

68+
public function testObjectInstanceStackedStub()
69+
{
70+
$user = new AdminUserModel(['name' => 'torreytsui']);
71+
double::registerObject($user, ['getName' => function () {
72+
return 'tsui';
73+
}]);
74+
double::registerObject($user, ['getName' => function () {
75+
return 'tt';
76+
}]);
77+
double::registerObject($user, ['getName' => function () {
78+
return __AM_CONTINUE__;
79+
}]);
80+
$name = $user->getName();
81+
$this->assertEquals('tt', $name);
82+
}
83+
5284
public function testStaticAccess()
5385
{
5486
$this->assertEquals('users', UserModel::tableName());

0 commit comments

Comments
 (0)