Skip to content

Commit 5025062

Browse files
atMost method has been created for limiting calls
1 parent c73c799 commit 5025062

File tree

5 files changed

+79
-1
lines changed

5 files changed

+79
-1
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,4 +643,24 @@ function test(Date $date):void
643643

644644
test($date);
645645

646+
```
647+
***Limiting calls***
648+
You can specify the maximum number of times the methods are called. For example, let's write a method that runs at most three times.
649+
```php
650+
$mockFactory = new MockFactory();
651+
652+
// Set the method to be called at most 3 times
653+
$mockFactory->atMost(3, 'now', function () {
654+
return '2012-2-2';
655+
});
656+
657+
$dateInstance = $mockFactory->createMock(Date::class);
658+
659+
echo $dateInstance->now(); // Outputs '2012-2-2'
660+
echo $dateInstance->now(); // Outputs '2012-2-2'
661+
echo $dateInstance->now(); // Outputs '2012-2-2'
662+
663+
// This will throw an exception after the third call
664+
echo $dateInstance->now(); // AtMostMethodException: Method now can be called only 3 times.
665+
646666
```

src/AtMostMethodException.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Zeus\Mock;
4+
5+
use RuntimeException;
6+
7+
class AtMostMethodException extends RuntimeException
8+
{}

src/MockFactory.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,24 @@ public function never(string $methodName): void
139139
$methodName, fn() => throw new NeverMethodException("Unexpected method call: $methodName. This method should never be invoked.")
140140
);
141141
}
142+
143+
/**
144+
* @param string $methodName
145+
* @return void
146+
*/
147+
public function atMost(int $count, string $methodName, mixed $response): void
148+
{
149+
$this->mockMethod->add($methodName, function (...$args) use ($count, $response, $methodName) {
150+
static $callCount = 0;
151+
if ($callCount >= $count) {
152+
throw new AtMostMethodException("Method $methodName must be called at most $count times.");
153+
}
154+
if ($response instanceof Closure) {
155+
$callCount++;
156+
return $response(...$args);
157+
}
158+
$callCount++;
159+
return $response;
160+
});
161+
}
142162
}

src/MockMethodInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function invokeMockedMethod(string $methodName, array $arguments): mixed;
3030
* @param Closure $response
3131
* @return $this
3232
*/
33-
public function mockMethod(string $methodName, Closure $response): MockMethod;
33+
public function mockMethod(string $methodName, mixed $response): MockMethod;
3434

3535
/**
3636
* @param string $methodName

tests/unit/AtMostMethodTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Zeus\Mock\Tests\unit;
4+
5+
use PHPUnit\Framework\Attributes\Test;
6+
use PHPUnit\Framework\TestCase;
7+
use Zeus\Mock\AtMostMethodException;
8+
use Zeus\Mock\MockFactory;
9+
use Zeus\Mock\Tests\stubs\Date;
10+
11+
class AtMostMethodTest extends TestCase
12+
{
13+
14+
15+
#[Test]
16+
public function atMostTest():void
17+
{
18+
19+
$mockFactory = new MockFactory();
20+
$mockFactory->atMost(3, 'now','2012');
21+
$dateInstance=$mockFactory->createMock(Date::class);
22+
23+
$this->assertEquals('2012', $dateInstance->now());
24+
$this->assertEquals('2012', $dateInstance->now());
25+
$this->assertEquals('2012', $dateInstance->now());
26+
27+
$this->expectException(AtMostMethodException::class);
28+
$dateInstance->now();
29+
}
30+
}

0 commit comments

Comments
 (0)