| Q | A
| --------------------| ---------------
| PHPUnit version | 9.0-dev
| PHP version | 7.4.2
| Installation Method | PHAR
If a test is expecting an exception and the tested method contains the yield keyword, the assertion does not work.
Using the following class:
<?php
final class SomeClass
{
public static function getSomeStuff(): iterable
{
throw new RuntimeException('Some error');
foreach (['One', 'Two', 'Three'] as $value) {
yield $value;
}
}
}
And the following test:
<?php
use PHPUnit\Framework\TestCase;
final class SomeClassTest extends TestCase
{
public function testExceptionIsThrown(): void
{
$this->expectException(RuntimeException::class);
SomeClass::getSomeStuff();
}
}
PHPUnit 9.0-dev by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 120 ms, Memory: 10.00 MB
There was 1 failure:
1) SomeClassTest::testExceptionIsThrown
Failed asserting that exception of type "RuntimeException" is thrown.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
PHPUnit 9.0-dev by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 91 ms, Memory: 10.00 MB
OK (1 test, 1 assertion)
Thanks a lot for your help!
A generator function does not execute immediately when you call it, it returns a Generator object. In order to actually execute your code, you need to start consuming the generator by e.g looping over it.
Here it's an example of how to trigger your exception:
<?php
use PHPUnit\Framework\TestCase;
final class SomeClass
{
public static function getSomeStuff(): iterable
{
throw new RuntimeException('Some error');
foreach (['One', 'Two', 'Three'] as $value) {
yield $value;
}
}
}
final class SomeClassTest extends TestCase
{
public function testExceptionIsThrown(): void
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Some error');
$generator = SomeClass::getSomeStuff();
$this->assertInstanceOf(Generator::class, $generator);
$generator->next();
}
}
PHPUnit output:
PHPUnit 9.5-g977a70658 by Sebastian Bergmann and contributors.
Runtime: PHP 7.4.3
Configuration: /workspace/phpunit/phpunit.xml
. 1 / 1 (100%)
Time: 00:00.004, Memory: 6.00 MB
OK (1 test, 3 assertions)
Oh yeah, does make sense. I changed my code as suggested and it works now, thank you @michaelpaul