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

6jjcrrmo  于 11个月前  发布在  PHP
关注(0)|答案(1)|浏览(137)

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

public function store(Request $request, Pipeline $pipeline)
{
    try {
        $request->validate([
            "name" => ["required", "max:512"],
            "stage" => ["required", "in:".Stage::toCSV()],
        ]);

        // Database interaction here (e.g., MyModel::create())

        return response()->json(["message" => trans("round.created")], 201);
    } catch (\Exception $e) {
        Log::error('Exception in MyController@store: ' . $e->getMessage());
        Log::error('Stack trace: ' . $e->getTraceAsString());
        return redirect()->back()->banner(trans('error'));
    }
}

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

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

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

13z8s7eq

13z8s7eq1#

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

use App\Models\MyModel;

class MyController extends Controller
{
    public function store(Request $request, MyModel $model, Pipeline $pipeline)
    {
        try {
            $request->validate([
                "name" => ["required", "max:512"],
                "stage" => ["required", "in:".Stage::toCSV()],
            ]);

            // Use the injected model for database interaction
            $model->create([
                // Your data here
            ]);

            return response()->json(["message" => trans("round.created")], 201);
        } catch (\Exception $e) {
            Log::error('Exception in MyController@store: ' . $e->getMessage());
            Log::error('Stack trace: ' . $e->getTraceAsString());
            return redirect()->back()->banner(trans('error'));
        }
    }
}

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

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

相关问题