methodWithAspect(); $this->fail('Expected AspectException to be thrown'); } catch (AspectException $e) { $this->assertEquals('Exception in before() method of aspect', $e->getMessage()); $this->assertEquals(ThrowingAspect::class, $e->aspectClass); $this->assertEquals('before', $e->method); $this->assertInstanceOf(\RuntimeException::class, $e->getPrevious()); $this->assertEquals('Exception thrown in before()', $e->getPrevious()->getMessage()); } } public function testExceptionInAfterIsWrappedInAspectException(): void { ThrowingAspect::$throwInAfter = true; $instance = new ThrowingClass(); try { $instance->methodWithAspect(); $this->fail('Expected AspectException to be thrown'); } catch (AspectException $e) { $this->assertEquals('Exception in after() method of aspect', $e->getMessage()); $this->assertEquals(ThrowingAspect::class, $e->aspectClass); $this->assertEquals('after', $e->method); $this->assertInstanceOf(\RuntimeException::class, $e->getPrevious()); $this->assertEquals('Exception thrown in after()', $e->getPrevious()->getMessage()); } } public function testMethodExecutesSuccessfullyWhenNoExceptions(): void { $instance = new ThrowingClass(); $result = $instance->methodWithAspect(); $this->assertEquals('success', $result); } }