Summer Sale! All accounts are 50% off this week.

losond's avatar

Argument 1 passed to App\Http\Controllers\LibraryController::TagParser() must be an instance of Illuminate\Http\Request, string given,

I am haveing trouble resolving this error I am getting for a unit test. The last ex of the Controller is what the full code will look like. However, I wanted take it a step at a time. I was able to get the test to pass using ($request) only in the controller. However I want to replace the function in the controller with what I have written in EXample.1 below. Whenever I run the unit test with EXample.1 I get the error directly following EXample.1 below:

EXample 1 : public function TagParser(Request $request)

There was 1 error:

1) Tests\UserControllerTest::test_it_gets_a_list_of_params
TypeError: Argument 1 passed to App\Http\Controllers\UserController::TagParser() must be an instance of Illuminate\Http\Request, string given, called in /PHP/tests/TagParserTest.php on line 22

Controller

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;

class UserController extends Controller
{
    public function TagParser($request) 
    {       
            return [$request];
    }

TagParserTest.php

<?php

namespace Tests;

use App\Http\Controllers\UserController;
use Illuminate\Http\Request;
use PHPUnit\Framework\TestCase;

class UserControllerTest extends TestCase
{
	public function test_it_gets_a_list_of_params()
	{
		$parser = new UserController;

		$result = $parser->TagParser("personal");
		$expected = ['personal'];

		$expected should match $result
		$this->assertSame($expected, $result);

	}
}

What am I missing from my TagParserTest to make the test run with the following:

Updated Controller

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Services\UserService;
use DB;

class UserController extends Controller
{
    public function TagParser(Request $request) 
    {       
        $username = $request->get('username');
        $currentLabel = $request->get('previousLabel');
        $newLabel = $request->get('updatedLabel');
        $currentNum = $request->get('previousNum);
        $newNum = $request->get('updatedNum');

        $UserService = new UserEditorService();
       $UserService->updateUser($username, $currentLabel, $newLabel, $currentNum, $newNum);

       return ['message' => 'User  has been updated successfully ', 'status' => 200];
    }
0 likes
12 replies
tykus's avatar

What is this unit test intended to achieve? Why not just make a feature test hitting the endpoint with valid data, and assert against the TestResponse?

losond's avatar

@tykus The purpose of this test is to take in a number of parameters that are passed in based on a user request. Inside the function I am setting those params to a variable and then passing those variables into the api call to update to the data.

I am new to PHP testing followed the tutorial. What references can you provide to accomplish the approach you suggested?

kokoshneta's avatar

I don’t quite understand what you’re actually asking.

You say you want to type-hint the $request argument to be a Request object, but in your test, you still do $parser->TagParser("personal"), passing it a string. That will always throw an exception. That’s not related to testing, just basic PHP. If you type-hint a function argument, you need to pass an argument of the correct type for the function to work.

losond's avatar

@kokoshneta My goal is to write a unit test . I am not sure how or where to start. So I followed a tutorial example on this site to write a basic unit test. I am attempting to alter the example unit test I followed to make it work for the following Controller below:

Purpose of this controller: The function is takes in a request. When the user interacts the a form the list of params are passed into that controller through the request. Inside the function of the controller I am am setting the params passed in to different variables. Then I am passing for variable to the another function stored inside the UserService component. I hope that makes sense.

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Services\UserService;
use DB;

class UserController extends Controller
{
    public function updateUser(Request $request) 
    {       
        $username = $request->get('username');
        $currentLabel = $request->get('previousLabel');
        $currentNum = $request->get('previousNum);

        $UserService = new UserEditorService();
       $UserService->updateUser($username, $currentLabel, $currentNum);

       return ['message' => 'User  has been updated successfully ', 'status' => 200];
    }

kokoshneta's avatar

@losond That much was clear to me. But as you say, “the function takes in a request” – the error you’re getting is because you’re not passing a request to the function.

If you change the parameter of the function from being a string "personal" to being an actual request object, it should work fine.

losond's avatar

@kokoshneta Does this appear to be what you suggested? If not what how should I correct it?

<?php

namespace Tests;

use App\Http\Controllers\UserController;
use Illuminate\Http\Request;
use App\Services\LibraryEditorService;
use PHPUnit\Framework\TestCase;
use DB;

class UserControllerTest extends TestCase
{
/** @test */
	public function it_gets_a_list_of_params()
	{

		//Arrange
		$parser = new UserController();
		$request = new Request(); 

		//Act
		$result = $parser->TagParcer($request,
			 [
			'username' => 'username',
			'currentLabel'    => 'currentLabel',
			'currentNum'    => 'currentNum'
			]);

		$expected = [
			'username' => 'username',
			'currentLabel'    => 'currentLabel',
			'currentNum'    => 'currentNum'
		];

		// Assert 
		$this->assertSame($expected, $result);
	}
kokoshneta's avatar

@losond Assuming that updateComponentLabelOrder() is comparable to TagParser() above, that should work, yes – or at least not throw an exception that the parameter is of the wrong type.

losond's avatar

@kokoshneta Thanks the original is no longer persisting. However, I received this error:


1) Tests\UserControllerTest::test_it_gets_a_list_of_params
Error: Class 'DB' not found

The error is pointing to the following lines in my controller. I am trying to figure out how to include this inside my unit test:

$UserService = new UserEditorService();
$UserService->updateUser($username, $currentLabel, $currentNum);
kokoshneta's avatar

@losond You have use DB at the top, which doesn’t make any sense, because there’s no class DB in the global namespace. You also don’t seem to reference any such class anywhere, at least not in the code you’ve shown here, so it seems unnecessary.

If it’s the Laravel DB class you’re trying to reference and you actually use it somewhere in your test case, it should be use Illuminate\Support\Facades\DB, since that’s where the database façade is located.

losond's avatar

@kokoshneta currently use DB is being used in both the Controller and UserEditorService files. When I received the message following error. I add use DB because I thought thats what was missing. I am going through some more tutorial a we speak to get a better understand on how to write this unit test.

1) Tests\UserControllerTest::test_it_gets_a_list_of_params
Error: Class 'DB' not found

It points to the files:

/var/www/PHP/app/Services/UserEditorService.php:428
whereas line 428 is:       /DB::beginTransaction();

/var/www/PHP/tests/UserControllerTest.php:24
whereas line  24:        $UserService->TagParcer('username', 'currentLabel', 'currentNum');

I do appreciate your assistance, patience, and suggestions

kokoshneta's avatar

@losond It looks like you need to learn the basics of PHP before you start writing unit tests. The use statement is a very basic, core feature of PHP, and you’re not using it in a way that makes sense.

Unit tests are a fairly complex thing. You can’t just jump in at the deep end and expect to make sense of Laravel unit tests if you don’t understand how PHP works. Learn basic PHP first, then move on to frameworks that use PHP, like Laravel.

losond's avatar

@kokoshneta is there a simple way to write this test from scratch? Seems simple in tutorials but in retrospect I am not grasping the basics enough to alter the example code to match mine. Im desperately in need of help

Please or to participate in this conversation.