Skip to content
This repository was archived by the owner on Feb 21, 2025. It is now read-only.

Commit 40f65fd

Browse files
committed
Better support for mocking concrete implementations and nullable params
1 parent 98bc39d commit 40f65fd

4 files changed

Lines changed: 55 additions & 6 deletions

File tree

src/HackMock.hh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
namespace Usox\HackMock;
44

5-
use Facebook\HackTest\HackTest;
5+
use type Facebook\HackTest\HackTest;
66

77
abstract class HackMock extends HackTest {
88

9+
<<__Override>>
910
public async function afterEachTestAsync(): Awaitable<void> {
1011
\Usox\HackMock\tear_down();
1112
}
12-
}
13+
}

src/Mock.hh

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,20 @@ final class Mock<TC> implements MockInterface {
3737
foreach ($rfl->getMethods() as $method) {
3838
$method_name = $method->getName();
3939

40+
if ($method_name === '__construct') {
41+
$gen_method = $this
42+
->code_generator
43+
->codegenMethod($method_name)
44+
->setReturnType('void');
45+
$class->addMethod($gen_method);
46+
continue;
47+
}
48+
4049
$gen_method = $this
4150
->code_generator
4251
->codegenMethod($method_name)
4352
->setReturnType('mixed')
53+
->setIsStatic($method->isStatic())
4454
->setBodyf(
4555
'return \Usox\HackMock\process_expectation(__CLASS__, \'%s\', vec(func_get_args()));',
4656
$method_name
@@ -64,19 +74,37 @@ final class Mock<TC> implements MockInterface {
6474
$parameter->getDefaultValue()
6575
);
6676
} else {
77+
$default_value = $parameter->getDefaultValue();
78+
$nullable = '';
79+
if (is_array($default_value)) {
80+
$default_value = '[]';
81+
}
82+
if ($parameter->allowsNull()) {
83+
$nullable = '?';
84+
}
6785
$gen_method->addParameterf(
68-
'%s $%s = %s',
86+
'%s%s $%s = %s',
6987
(string) $parameter->getType(),
88+
$nullable,
7089
$parameter->getName(),
71-
$parameter->getDefaultValue()
90+
$default_value
7291
);
7392
}
7493
}
7594
} else {
95+
$nullable = '';
96+
$default = '';
97+
$type = Str\trim((string) $parameter->getType());
98+
if ($parameter->allowsNull()) {
99+
$nullable = '?';
100+
$default = ' = null';
101+
}
76102
$gen_method->addParameterf(
77-
'%s $%s',
78-
$parameter->getTypehintText(),
103+
'%s%s $%s%s',
104+
$nullable,
105+
$type,
79106
$parameter->getName(),
107+
$default
80108
);
81109
}
82110
}

tests/SampleBaseClass.hh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<?hh // strict
22

33
class SampleBaseClass {
4+
5+
public function __construct(): void {
6+
throw new \Exception('Should never be thrown');
7+
}
48

59
public function noParamsAndVoid(): void {
610

@@ -10,4 +14,10 @@ class SampleBaseClass {
1014
return $some_int;
1115
}
1216

17+
public function intOrNullWithDefault(?int $some_int = null): void {
18+
}
19+
20+
public static function someStaticFunction(): void {
21+
22+
}
1323
}

tests/SampleTest.hh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,14 @@ class SampleTest extends \Usox\HackMock\HackMock {
262262
)
263263
->toBeSame($int2);
264264
}
265+
266+
public function testIntOrNullWithDefaultOnBaseClass(): void {
267+
$sample = mock(SampleBaseClass::class);
268+
269+
prospect($sample, 'intOrNullWithDefault')
270+
->with(55)
271+
->once();
272+
273+
$sample->intOrNullWithDefault(55);
274+
}
265275
}

0 commit comments

Comments
 (0)