You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Post请求测试断言方法报错及无断言警告问题咨询

Laravel API测试问题:POST请求断言报错/无断言警告

问题描述

我是Laravel框架测试新手,在测试API的POST端点时,使用assertOk()、assertStatus()等断言方法会报错;但去掉断言后,测试又会出现“未执行任何断言”的警告。

测试代码

<?php

namespace Tests\Feature;

use Illuminate\Http\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
use Tests\TestCase;

class LocationTest extends TestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function test_get_all_report()
    {
        Http::fake([
            'http://127.0.0.1:8000/*' => Http::response([
                [
                    "latitude"=> "1.56786467",
                    "longitude"=> "-0.056789685",
                    "message"=> "test test that's a place of risk"  
                ],
                [
                    "latitude"=> "1.56786467",
                    "longitude"=> "-0.056789685",
                    "message"=> "test test that's a place of risk"  
                ]                
            ], 200),
        ]);

        $response = $this->getJson('api/get-all-signal-zone')->assertStatus(200);
    }

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function test_get_all_report_catch_error()
    {
        Http::fake([
            'http://127.0.0.1:8000/*' => Http::response([
                [
                    "message"=> "Server error"  
                ]
            ], 500),
        ]);

        $response = $this->getJson('api/get-all-signal-zone')->assertStatus(Response::HTTP_INTERNAL_SERVER_ERROR);
    }
    
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function test_get_all_report_by_date()
    {
        Http::fake();

        $response = Http::post('http://127.0.0.1:8000/api/get-all-signal-zone-by-date', [
            "date"=> "2022-11-10"
        ]);

    }
}

路由文件

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\LocationController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::get('/get-all-signal-zone', [LocationController::class, 'all']);
// Route::get('/get-all-signal-zone-by-date/{date}', [LocationController::class, 'getLocationByDate'])->name('reporting_by_date');
Route::post('/get-all-signal-zone-by-date', [LocationController::class, 'getLocationByDate']);
Route::post('/send-signal-zone', [LocationController::class, 'save']);

控制器代码

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Repositories\Location\LocationRepository;

/**
 * Description of LocationController
 *
 * @author Amoungui
 */
class LocationController extends Controller
{
    public function __construct(LocationRepository $locationRepository) {
        $this->locationRepository = $locationRepository;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function all(){
        return $this->locationRepository->list(); 
    }

    /**
     * View a list of the resource based on a date.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function getLocationByDate(Request $request){
        return $this->locationRepository->getByDate($request->date);
    }

    /**
     * Save a newly created resource in external api.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */    
    public function save(Request $request){
        $response = $this->locationRepository->store($request->all());
        if($response->successful()){
            return response()->json([
                'status' => true,
                'message' => "location submited successfully",
                'data' =>  $request->all()
            ], 201);
        }
        
        return response()->json([
            'data' => null,
            'message' => 'Failed',
        ], 500);
    }
}

测试报错信息

WARN Tests\Feature\LocationTest
✓ get all report
✓ get all report catch error
! get all report by date → This test did not perform any assertions C:\wamp64\www\backend-11-user-story-reporting-of-a-place-in-danger\tests\Feature\LocationTest.php:61

Tests: 1 risky, 4 passed
Time: 0.64s

解决方案

核心问题

你的POST测试用错了方法:

  1. Http::post()是Laravel用于在应用代码中发起外部HTTP请求的工具,返回的是Illuminate\Http\Client\Response对象,它不支持assertStatus()这类测试断言方法,所以加断言会报错。
  2. 测试自己的API端点,必须用测试类提供的$this->postJson()方法,它返回的Illuminate\Testing\TestResponse对象支持所有Laravel测试断言。
  3. 你之前fake自己的API地址完全没必要——Http::fake()是用来模拟控制器/仓库层调用的外部API,而非自己的API。

修改后的POST测试代码

public function test_get_all_report_by_date()
{
    // 若你的LocationRepository::getByDate()调用了外部API,在此fake该外部接口的响应
    Http::fake([
        // 替换为仓库实际调用的外部API地址规则
        'your-external-api.com/*' => Http::response([
            [
                "latitude"=> "1.56786467",
                "longitude"=> "-0.056789685",
                "message"=> "test test that's a place of risk"  
            ]
        ], 200),
    ]);

    // 用$this->postJson()测试自身API端点
    $response = $this->postJson('api/get-all-signal-zone-by-date', [
        "date" => "2022-11-10"
    ]);

    // 添加断言,解决无断言警告并验证API响应
    $response->assertStatus(200);
    // 可根据需求添加更多断言,比如验证返回的JSON结构
    // $response->assertJsonStructure([
    //     '*' => ['latitude', 'longitude', 'message']
    // ]);
}

额外说明

  • 如果getByDate()方法没有调用外部API,完全不需要Http::fake(),直接调用$this->postJson()并添加断言即可。
  • 所有测试自身API的场景,都应使用$this->getJson()、$this->postJson()等测试方法,而非Http::*系列方法。

内容的提问来源于stack exchange,提问作者Serge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:55:30