Laravel 5.5 中 PHP 单元测试中的类验证器错误

Posted

技术标签:

【中文标题】Laravel 5.5 中 PHP 单元测试中的类验证器错误【英文标题】:Class Validator error in Php Unit Testing in Laravel 5.5 【发布时间】:2020-02-19 00:49:44 【问题描述】:

我正在 laravel 5.5 中进行 phpUnit 测试。当我尝试通过创建请求对象并将其作为参数传递来使用 2 种不同的方法在控制器上测试该方法时,我遇到了同样的错误,但是当我在 Postman 上测试时它工作正常

"ReflectionException: 类验证器不存在 /src/vendor/laravel/framework/src/Illuminate/Container/Container.php:752 /src/vendor/laravel/framework/src/Illuminate/Container/Container.php:631 /src/vendor/laravel/framework/src /Illuminate/Container/Container.php:586 /src/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:732 /src/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:110 /src/vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php:96 /src/vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php:44"

编写测试用例的两种方法

1)

$response = $this->withHeaders([ 'Content-type' => 'application/json' ])->json('POST', '/account', $jsonArr);

2)

$request = Request::create('/account', 'POST', $jsonArr); 
   $request->headers->set('Content-type', 'application/json'); 
   $controller = new AccountController;
   $response = $controller->create($request);

我的代码:

************************AccountController.php************************ **********

<?php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\Validator;
use App\Models\Account;

class AccountController extends Controller

    public function create(Request $request)
        
        $this->validate($request, $this->rules());          
        $service_name = "seller-registration-accepted";
        $id_array = array();
        $link_array = array();
        $account = new Account;
        $account->id = $account_id;
        $account->company_name = $request->company_name;
        $account->email = $request->email;
        $account->phone = $request->phone;
        $account->address = $request->address;
        $account->language = $request->language;
        $account->account_type_id = 5;
        $this->insertCompanyDescription($request, $account_id);
        $customerRes = PaymentGatewayUtil::createCustomer();
        if (((json_decode($customerRes))->status == "success")) 
            $customer = new Customer;
            $customer->account_id = $account_id;
            $customer->id =  ((json_decode($customerRes))->data)->customer_id;
            $customer->save();
        
        return JSendResponse::success(['message' =>
        'Seller registration accepted successfully, seller account created.',
        'id' => $account->id]);
    

    private function rules()
    
        return [
            'company_name' => 'sometimes',
            'email' => 'required|email',
            'phone' => 'required',
            'language' => 'required',
            'account_type' => 'required',
            'translations' => 'sometimes',
            'translations.*.company_description' => 'required',
            'translations.*.locale' => 'required',
            'website_link' => 'sometimes|URL'
        ];
    

 

**************************AccountControllerTest.php****************** ***

<?php
namespace Tests\Feature;

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use App\Http\Controllers\AccountController;
use Exception;

class AccountControllerTest extends TestCase

    public function testCreateTest()
    
        $uniqueEmailAddress = "test_".rand(1000, 9999)."@gmail.com";
        $jsonArr = array();
        $jsonArr['email'] = $uniqueEmailAddress;
        $jsonArr['company_name'] = "test_47";
        $jsonArr['address'] = "XYZ";
        $jsonArr['service_type'] = 'partner';
        $jsonArr['account_type'] = 'seller';
        $jsonArr['language'] = 'en';
        $jsonArr['phone'] = '00000000000';
        $response =  $this->withHeaders([
              'Content-type' => 'application/json'
         ])->json('POST', '/account', $jsonArr);
    



    public function testCreateTest2()
    
        $uniqueEmailAddress = "test2_".rand(1000, 9999)."@gmail.com";
        $jsonArr = array();
        $jsonArr['email'] = $uniqueEmailAddress;
        $jsonArr['company_name'] = "test_23";
        $jsonArr['address'] = "XYU";
        $jsonArr['service_type'] = 'partner';
        $jsonArr['account_type'] = 'seller';
        $jsonArr['language'] = 'en';
        $jsonArr['phone'] = '00000000000';


        $request = $this->convertToRequest($jsonArr);
        $request = Request::create('/account', 'POST', $jsonArr);
        $request->headers->set('Content-type', 'application/json');
        $controller = new AccountController;
        $response = $controller->create($request);
        
     

**********************routes/api.php************************ ***

<?php


Route::post('/account', 'AccountController@create'); 

【问题讨论】:

【参考方案1】:

我认为您应该使用 laravel 测试辅助方法改进您的测试方法,而不是尝试模拟请求,因为您不会完全加载中间件和请求依赖项。

类似的东西。

<?php

    public function testCreateTest2()
        
            $uniqueEmailAddress = "test2_".rand(1000, 9999)."@gmail.com";
            $jsonArr = array();
            $jsonArr['email'] = $uniqueEmailAddress;
            $jsonArr['company_name'] = "test_23";
            $jsonArr['address'] = "XYU";
            $jsonArr['service_type'] = 'partner';
            $jsonArr['account_type'] = 'seller';
            $jsonArr['language'] = 'en';
            $jsonArr['phone'] = '00000000000';

            $response = $this->json('POST', '/account', $jsonArr);

            $response->assertStatus(200)
            ->assertJsonFragment(['message' => 'Seller registration accepted successfully, seller account created.'])
            
         

并且可能创建另一个测试来测试验证器

<?php

    public function testCreateTest2()
        
            $uniqueEmailAddress = "";
            $jsonArr = array();
            $jsonArr['email'] = $uniqueEmailAddress;
            $jsonArr['company_name'] = "test_23";
            $jsonArr['address'] = "XYU";
            $jsonArr['service_type'] = 'partner';
            $jsonArr['account_type'] = 'seller';
            $jsonArr['language'] = 'en';
            $jsonArr['phone'] = '00000000000';

            $response = $this->json('POST', '/account', $jsonArr);

            $response->assertStatus(422)
            ->assertJsonFragment(['email' => 'Email is required.'])
            
         

【讨论】:

以上是关于Laravel 5.5 中 PHP 单元测试中的类验证器错误的主要内容,如果未能解决你的问题,请参考以下文章

如果在Laravel 5.5单元测试中隐藏密码,如何模拟用户创建

Laravel 5.5 找不到具有正确命名空间的类

Predis 与 laravel 5.5 “Aggregate/RedisCluster.php:337 中的池中没有可用连接”

Laravel 5.5 路由中的模型绑定不起作用

php 在Laravel 5.5中更改公共路径

PHP单元,使用单元测试测试laravel日志消息