A
A
Andrey Boychenko2021-12-07 16:01:56
PHPUnit
Andrey Boychenko, 2021-12-07 16:01:56

Mockery::on() - testing closure?

There is a code with closure - which cannot be covered with tests. I looked at the documentation of laravel, phpunit, but I could not find a clear explanation for myself.

Here is a piece of code that I cannot cover with tests

$ganeshaRateBuilder = $this->rateBuilder
            ->adapter($adapter)
            ->storageKeys(new StorageKeys())
            ->minimumRequests(10)
            ->failureRateThreshold(50)
            ->intervalToHalfOpen(10)
            ->timeWindow(30)
            ->build();

//Здесь упростил код, на самом деле в close есть условия, которые выполняются в зависимости от значения $event
        $ganeshaRateBuilder->subscribe(function ($event, $service, $message) {
            $this->toSlack(config('slack.channels.circuit'), "circuit is open for $service");
        });


Here is a test that does not cover and crashes with an error
/** @var Ganesha|MockObject $ganesha */
        $ganesha = $this->getMockBuilder(Ganesha::class)
            ->disableOriginalConstructor()
            ->onlyMethods(['subscribe'])
            ->getMock();

$closure = Mockery::on(function ($closure) use ($event, $service, $message) {
            $circuitBreaker = Mockery::mock(CircuitBreaker::class);
            $circuitBreaker->shouldReceive('toSlack')->once()->with(config('slack.channels.circuit'), "circuit is open for $service");

            $closure($event, $service, $message);

            return true;
        });

$ganesha
            ->expects($this->once())
            ->method('subscribe')
            ->with($closureMethod)
            ->willReturnSelf();


but if in with() substitute
$closureMethod = function ($event, $service, $message) {
            
        };


Then the test will be successfully executed, but the truth is, the test coverage is 0.
Here is the text of the error


1) Tests\Unit\Services\CircuitBreaker\CircuitBreakerTest::it_should_return_circuit_breaker_instance
Expectation failed for method name is "subscribe" when invoked 1 time(s)
Parameter 0 for invocation Ackintosh\Ganesha::subscribe(Closure Object (...)): void does not match expected value.
Closure Object &0000000001f786fa0000000008db000d (
0 => Closure Object &0000000001f786fa0000000008db000d
) is not instance of expected class "Mockery\Matcher\Closure".
--- Expected
+++ Actual
@@ @@
-Mockery\Matcher\Closure Object &0000000001f786d70000000008db000d (
- '_expected' => Closure Object &0000000001f786ab0000000008db000d (
- 0 => Closure Object &
- )
+Closure Object &0000000001f786fa0000000008db000d (
+ 0 => Closure Object &0000000001f786fa0000000008db000d
)

Where am I wrong?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question