{"record":{"id":"813c5463905dec95","repo":"sebastianbergmann/phpunit","slug":"failed-asserting-that-exception-with-message-s","errorCode":null,"errorMessage":"Failed asserting that exception with message %s \"%s\" is thrown","messagePattern":"Failed asserting that exception with message (.+?) \"(.+?)\" is thrown","errorType":"exception","errorClass":"AssertionFailedError","httpStatus":null,"severity":"error","filePath":"src/Framework/TestCase/ExceptionExpectation.php","lineNumber":153,"sourceCode":"                ),\n            );\n        }\n    }\n\n    /**\n     * @throws AssertionFailedError\n     */\n    public function assertWasRaised(TestCase $test): void\n    {\n        if ($this->expectedException !== null) {\n            Assert::assertThat(\n                null,\n                new ExceptionConstraint($this->expectedException),\n            );\n        } elseif ($this->expectedMessageConstraint !== null) {\n            $test->addToAssertionCount(1);\n\n            throw new AssertionFailedError(\n                sprintf(\n                    'Failed asserting that exception with message %s \"%s\" is thrown',\n                    $this->expectedMessageConstraint instanceof ExceptionMessageIs ? 'is' : 'containing',\n                    $this->expectedMessage,\n                ),\n            );\n        } elseif ($this->expectedMessageRegularExpression !== null) {\n            $test->addToAssertionCount(1);\n\n            throw new AssertionFailedError(\n                sprintf(\n                    'Failed asserting that exception with message matching \"%s\" is thrown',\n                    $this->expectedMessageRegularExpression,\n                ),\n            );\n        } elseif ($this->expectedCode !== null) {\n            $test->addToAssertionCount(1);\n","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Framework/TestCase/ExceptionExpectation.php#L135-L171","documentation":"Thrown by ExceptionExpectation::assertWasRaised() when the test set expectExceptionMessage() (or expectExceptionMessageMatches-like message constraint) but no exception was raised during the test at all. Because assertWasRaised() only runs when nothing was thrown, it cannot compare a message and fails immediately with 'is' for exact or 'containing' for substring expectations.","triggerScenarios":"Calling $this->expectExceptionMessage('...') without the code under test throwing any exception; expectExceptionMessage() used alone (no expectException()) and the happy path completes normally.","commonSituations":"Code fixed so the exception no longer occurs while the test still expects one; exception thrown only under a condition the test no longer arranges; expectExceptionMessage() set before a code path that silently succeeds.","solutions":["Verify the tested code actually throws on the input the test arranges","Arrange the failing precondition (bad input, missing dependency, etc.) so the exception path is reached","If the behavior intentionally no longer throws, delete the expectExceptionMessage() call and assert the successful result instead"],"exampleFix":"// before\n$this->expectExceptionMessage('Division by zero');\n$calc->divide(10, 2); // valid input, no exception thrown\n\n// after\n$this->expectExceptionMessage('Division by zero');\n$calc->divide(10, 0);","handlingStrategy":"validation","validationCode":"// Inside the test, make the throwing path explicit so a silent pass is impossible:\nself::assertTrue(\n    method_exists($calc, 'divide'),\n    'precondition: method under test exists',\n);\n$this->expectExceptionMessage('Division by zero');\n$calc->divide(10, 0);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair expectExceptionMessage() with an expectException() call and arrange the failing input","Review expectation-based tests after changing error handling in production code"],"tags":["phpunit","exception-assertion","assertion-failed","expected-exception"],"backgroundTag":"expected-exception-message-not-thrown","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}