Why doesn’t PHPUnit do last exception assertion in this code?
public function testConfigOverriding()
{
$this->dependencyContainer = new DependencyContainer(__DIR__ . "/../../Resources/valid_json.json");
$this->assertEquals('overriden', $this->dependencyContainer->getConfig('shell_commander')['pygmentize_command']);
$unexisting = "unexisting_file";
$this->setExpectedException('Exception', "Configuration file at path \"$unexisting\" doesn't exist.");
$this->dependencyContainer = new DependencyContainer($unexisting);
$invalid = __DIR . "/../../Resources/invalid_json.json";
$this->setExpectedException('Exception', "Configuration JSON file provided is not valid.");
$this->dependencyContainer = new DependencyContainer($invalid);
}
So basically: it tests whether “unexsisting_file” exception was thrown, but completely ignores “invalid json” test. Do I need to make separate tests for each exception thrown?
Even with
setExpectedException, your test is still regular PHP code, and follows PHP’s normal rules. If an exception is thrown, program flow immediately jumps out of the current context until it reaches atry/catchblock.In PHPUnit, when you use
setExpectedException, it tells PHPUnit’s core that when it should be expecting an exception from the code that’s about to run. It therefore waits for it with atry/catchblock and passes the test if thecatchis called with the type of exception it is expecting.However, within your test method, the normal PHP rules still apply — when the exception happens, that’s the end of the current code block. Nothing more in that method will be executed, unless you have your own
try/catchblock within the test method.So therefore, in order to test multiple exceptions, you have a few options:
Add your own
try/catchto the test method, so that you can carry on with further tests within that method after the first exception.Split the tests into separate methods, so that each exception is in its own test.
This particular example looks like a good case to use PHPUnit’s
dataProvidermechanism, because you’re basically testing the same functionality with two sets of data. ThedataProviderfeature allows you to define a separate function that contains an array of input data for each set of values you want to test. These values are then passed one set at a time into the test method. Your code would look something like this: