如何在laravel PHPunit测试中触发异常

6jjcrrmo  于 2024-01-05  发布在  PHP
关注(0)|答案(1)|浏览(199)

我在尝试测试Laravel控制器中涉及数据库交互的异常处理时遇到了一个问题。具体来说,我想测试控制器的store方法中异常的catch块。store方法看起来像这样:

  1. public function store(Request $request, Pipeline $pipeline)
  2. {
  3. try {
  4. $request->validate([
  5. "name" => ["required", "max:512"],
  6. "stage" => ["required", "in:".Stage::toCSV()],
  7. ]);
  8. // Database interaction here (e.g., MyModel::create())
  9. return response()->json(["message" => trans("round.created")], 201);
  10. } catch (\Exception $e) {
  11. Log::error('Exception in MyController@store: ' . $e->getMessage());
  12. Log::error('Stack trace: ' . $e->getTraceAsString());
  13. return redirect()->back()->banner(trans('error'));
  14. }
  15. }

字符串
这是我迄今为止尝试的。

  1. $this->mock(\App\Models\MyModel::class, function ($mock) {
  2. $mock->shouldReceive('create')
  3. ->once()
  4. ->andThrow(new \Exception('Simulated exception'));
  5. });
  1. $this->mock(\Exception::class, function ($mock) {
  2. $mock->shouldReceive('getMessage')->andReturn('Mocked exception message');
  3. });

的数据
如果您对如何正确地模拟数据库交互以模拟异常并测试catch块有任何建议或指导,我们将不胜感激。
谢谢你,谢谢

13z8s7eq

13z8s7eq1#

在Laravel控制器的store方法中测试异常的catch块的最佳方法是模拟数据库交互,以便它抛出异常。为此,您需要模拟MyModel类,以便在create方法调用期间抛出异常。为此,我建议将模型作为控制器的依赖项注入,以便您可以创建一个模拟模型,并通过它测试其功能

  1. use App\Models\MyModel;
  2. class MyController extends Controller
  3. {
  4. public function store(Request $request, MyModel $model, Pipeline $pipeline)
  5. {
  6. try {
  7. $request->validate([
  8. "name" => ["required", "max:512"],
  9. "stage" => ["required", "in:".Stage::toCSV()],
  10. ]);
  11. // Use the injected model for database interaction
  12. $model->create([
  13. // Your data here
  14. ]);
  15. return response()->json(["message" => trans("round.created")], 201);
  16. } catch (\Exception $e) {
  17. Log::error('Exception in MyController@store: ' . $e->getMessage());
  18. Log::error('Stack trace: ' . $e->getTraceAsString());
  19. return redirect()->back()->banner(trans('error'));
  20. }
  21. }
  22. }

字符串
或者你可以选择基于服务的方法。在这两种情况下,你都可以模拟模型/服务,然后将模拟的依赖注入到你的控制器中并测试它。
要创建mock,您可以使用mock builder或mock,
一个匿名类

  1. $modelMock = new class extends MyModel {
  2. public static function create(array $attributes = [])
  3. {
  4. // Throw an exception when create is called
  5. throw new \Exception('Simulated exception');
  6. }
  7. };

展开查看全部

相关问题