0
votes

I am working on phpUnit test in laravel 5.5. When I am trying to test the method on controller with 2 different methods by creating request object and pass it as a parameter, I am getting same error but It is working fine when I am testing on Postman

"ReflectionException: Class validator does not exist /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"

Two method of writing test cases

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);

My Code:

********************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

1 Answers

0
votes

I think you should improve your testing approach using the laravel testing helper methods instead of trying to emulate the request, because you are not going to have fully loaded the middlewares and request dependencies.

something like this.

<?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.'])
            }
        } 

And maybe create another test to test the validator

<?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.'])
            }
        }