Testing a closure in Prophecy

A couple of times I’ve had to try and figure out how to test closures in Prophecy. Here’s how I did it.

<?php
public function setWarningCallback() {
    $log = $this->log;

    $this->dependency->setCallback(function (Thing $thing) use ($log) {
         if ($thing->hasSomeState()) {
            $log->warning('Thing has x state but going ahead with action anyway;', [$thing]);
         }

         return $thing->action();
    });
}
<?php
public function test_callback_does_warning_and_then_does_action()
{
    $log = $this->log;

    $logs_warning_on_some_state = function (Closure $callback) use ($log) {
        $thing = $this->prophesize(Thing::class);
        $thing->hasSomeState()->willReturn(true);

        $log->warning('Thing has x state but going ahead with action anyway;', [$thing])
           ->shouldBeCalled();

        $callback($thing->reveal());

        return true;
    };

    $this->unit->setWarningCallback();

    $this->dependency->setCallback(Argument::that($logs_warning_on_some_state))
       ->shouldHaveBeenCalled();
}

Although this does regretable destroy the nice setup, execute, assert pattern. There’s probably a better way, but whatever, this works for the time being.