1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
<?php
declare(strict_types=1);
namespace malkusch\lock\Tests\mutex;
use malkusch\lock\exception\LockAcquireException;
use malkusch\lock\exception\LockReleaseException;
use malkusch\lock\mutex\LockMutex;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class LockMutexTest extends TestCase
{
/** @var LockMutex&MockObject */
private $mutex;
#[\Override]
protected function setUp(): void
{
parent::setUp();
$this->mutex = $this->getMockBuilder(LockMutex::class)
->onlyMethods(['lock', 'unlock'])
->getMock();
}
/**
* Tests lock() fails and the code is not executed.
*/
public function testLockFails(): void
{
$this->expectException(LockAcquireException::class);
$this->mutex->expects(self::once())
->method('lock')
->willThrowException(new LockAcquireException());
$this->mutex->synchronized(static function (): void {
self::fail('Should not execute code');
});
}
/**
* Tests unlock() is called after the code was executed.
*/
public function testUnlockAfterCode(): void
{
$this->mutex->expects(self::once())
->method('unlock');
$this->mutex->synchronized(static function (): void {});
}
/**
* Tests unlock() is called after an exception.
*/
public function testUnlockAfterException(): void
{
$this->mutex->expects(self::once())
->method('unlock');
$this->expectException(\DomainException::class);
$this->mutex->synchronized(static function () {
throw new \DomainException();
});
}
/**
* Tests unlock() fails after the code was executed.
*/
public function testUnlockFailsAfterCode(): void
{
$this->expectException(LockReleaseException::class);
$this->mutex->expects(self::once())
->method('unlock')
->willThrowException(new LockReleaseException());
$this->mutex->synchronized(static function () {});
}
/**
* Tests unlock() fails after the code threw an exception.
*/
public function testUnlockFailsAfterException(): void
{
$this->expectException(LockReleaseException::class);
$this->mutex->expects(self::once())
->method('unlock')
->willThrowException(new LockReleaseException());
$this->mutex->synchronized(static function () {
throw new \DomainException();
});
}
/**
* Tests the code result is available in LockReleaseException.
*/
public function testCodeResultAvailableAfterFailedUnlock(): void
{
$this->mutex->expects(self::once())
->method('unlock')
->willThrowException(new LockReleaseException());
try {
$this->mutex->synchronized(static function () {
return 'result';
});
} catch (LockReleaseException $exception) {
self::assertSame('result', $exception->getCodeResult());
self::assertNull($exception->getCodeException());
}
}
/**
* Tests the code exception is available in LockReleaseException.
*/
public function testCodeExceptionAvailableAfterFailedUnlock(): void
{
$this->mutex->expects(self::once())
->method('unlock')
->willThrowException(new LockReleaseException());
try {
$this->mutex->synchronized(static function () {
throw new \DomainException('Domain exception');
});
} catch (LockReleaseException $exception) {
self::assertInstanceOf(\DomainException::class, $exception->getCodeException());
self::assertSame('Domain exception', $exception->getCodeException()->getMessage());
}
}
}
|