Let's talk about what happens if some Exceptions appear, and you want to test if a particular Exception is successfully thrown in your tests.
Exception Example 1
Imagine a scenario where, in a Service, you throw an Exception. It may be your custom Exception or a Laravel Exception like ModelNotFound
.
In this example, we throw our custom Exception if the currency rate doesn't exist.
namespace App\Services; use Illuminate\Support\Arr;use App\Exceptions\CurrencyRateNotFoundException; class CurrencyService{ const RATES = [ 'usd' => [ 'eur' => 0.98 ], ]; public function convert(float $amount, string $currencyFrom, string $currencyTo): float { if (! Arr::exists(self::RATES, $currencyFrom)) { throw new CurrencyRateNotFoundException('Currency rate not found'); } $rate = self::RATES[$currencyFrom][$currencyTo] ?? 0; return round($amount * $rate, 2); }}
Another example: in the Model, you have an attribute to show a converted price, but in case of an Exception, you log, alert, or do something else.
use App\Services\CurrencyService;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Casts\Attribute;use App\Exceptions\CurrencyRateNotFoundException;use Illuminate\Database\Eloquent\Factories\HasFactory; class Product extends Model{ protected $fillable = [ 'name', 'price', ]; protected function eurPrice(): Attribute { return Attribute::make( get: function () { try { return (new CurrencyService())->convert($this->price, 'usd', 'eur'); } catch (CurrencyRateNotFoundException $e) { // Log something, alert someone } }, ); }}
The Test
This test is going to be a Unit test, not a Feature. We're not testing...