PHPUnit Error: Call to undefined method Tests\Unit\ExampleTest::visit() - laravel

This is the test case I've written and when i try to run it with this command vendor/bin/phpunit on linux it gives me the error "Call to undefined method Tests\Unit\ExampleTest::visit()"
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$this->visit('/Login')
->type('KP123#gmail.com','email')
->type('123456','password')
->press('Login')
->seePageIs('/home')
->see('Katy Perry');
}
}
I've tried running composer update and it still could not work. Had Anyone experienced this issue before?

The visit() method looks like it's part of the SeleniumTestCase. So my guess is you either extend from the wrong base class. I assume it should look something like this:
class ExampleTest extends \PHPUnit_Extensions_Selenium2TestCase
{
// your test method
}
edit: I just noticed the Laravel tag, so it's probably more something like Illuminate\Foundation\Testing\TestCase. If this gives you errors that it can't find the class you have to set the bootstrap file in your phpunit.xml to the vendor/autoload.php or another appropriate bootstrap file where the file is registered in the autoloader.

I might have come in late onto this question but here is my 2 cents. I have been trying to use the same methods with my test case which led to a dismal failure.
I the realised that I could actually make use of the TestResponse class which is found on the Foundation namespace that wraps many methods around the response object.
$this->get('/url/to/visit'); //Then you can make your assertions on the returned response.
In my case I had authentication turned on for the application therefore it always complained about the header view where we display the username of the currently logged in user. If you run into that situation then use the Auth Facade like shown below:
\Auth::loginUsingId(1);
You should now be able to assert that your response has some text in it. Hope this helps. By the way I am on Laravel 5.4

If you are using new version of Laravel you must use Laravel Dusk to use similar methods to $this->visit or see. It was excluded from Laravel around version 6.
Instead you can use, but it has limited options:
$this->get('/Login')

composer require laravel/browser-kit-testing --dev
Try this

if you are using > Laravel 8 try :
$this->get('/Login')
instead of visit function, and assertSeeText instead of see

Related

test user can view a login form

I'm new to testing with Laravel and im testing someone else's application
im trying to simply test whether a user can view a login form
So far i have this
class LoginTest extends TestCase
{
public function test_user_can_view_a_login_form()
{
$response = $this->get('/login');
$response->assertSuccessful();
$response->assertViewIs('auth.login');
}
}
But i have an undefined method 'get' and i cant figure out what the issue is ive also tried Route::get but i get an error with that as well
Any help would be appreciated thanks
You need to extend from Laravel TestCase that is placed in tests folder. Now, you're using phpunit Testcase which haven't basic setup for http request and many others laravel tools.
Follow below steps:
Create a feature test using php artisan make:test LoginTest
Define your test_user_can_view_a_login_form method in it.

Laravel app deployment in Heroku fails with handling the post-autoload-dump event returned with error code 1 [duplicate]

I have been using Eloquent as a standalone package in Slim Framework 2 successfully.
But now that I want to make use of Illuminate\Support\Facades\DB since I need to show some statistics by getting the info from 2 tables and using a Left Join and a Counter from the database like this:
use Illuminate\Support\Facades\DB;
$projectsbyarea = DB::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id');
I get the following error:
Type: RuntimeException
Message: A facade root has not been set.
File: ...\vendor\illuminate\support\Facades\Facade.php
Line: 206
How can I solve it?
So far I have found out, in this link that I need to create a new app container and then bind it to the Facade. But I haven't found out how to make it work.
This is how I started the rest of my Eloquent and working fine:
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule();
$capsule->addConnection([
'my' => $app->config->get('settings'),
/* more settings ...*/
]);
/*booting Eloquent*/
$capsule->bootEloquent();
How do I fix this?
Fixed
As #user5972059 said, I had to add $capsule->setAsGlobal();//This is important to make work the DB (Capsule) just above $capsule->bootEloquent();
Then, the query is executed like this:
use Illuminate\Database\Capsule\Manager as Capsule;
$projectsbyarea = Capsule::table('projects AS p')
->select(DB::raw('DISTINCT a.area, COUNT(a.area) AS Quantity'))
->leftJoin('areas AS a','p.area_id','=','a.id')
->where('p.status','in_process')
->where('a.area','<>','NULL')
->orderBy('p.area_id')
->get();
You have to change your code to:
$Capsule = new Capsule;
$Capsule->addConnection(config::get('database'));
$Capsule->setAsGlobal(); //this is important
$Capsule->bootEloquent();
And at the beginning of your class file you have to import:
use Illuminate\Database\Capsule\Manager as DB;
I have just solved this problem by uncommenting $app->withFacades(); in bootstrap/app.php
Had the same issue with laravel 8. I replaced
use PHPUnit\Framework\TestCase;
with:
use Tests\TestCase;
Try uncommenting in app.php $app->withFacades();
Do not forget to call parent::setUp(); before.
fails
public function setUp(): void {
Config::set('something', true);
}
works
public function setUp(): void {
parent::setUp();
Config::set('something', true);
}
One random problem using phpUnit tests for laravel is that the laravel facades have not been initialized when testing.
Instead of using the standard PHPUnit TestCase class
class MyTestClass extends PHPUnit\Framework\TestCase
one can use
class UserTest extends Illuminate\Foundation\Testing\TestCase
and this problem is solved.
I got this error after running:
$ php artisan config:cache
The solution for me was to delete the /bootstrap/cache/config.php file. I'm running Laravel 5.5.
The seems to arise in multiple situation, and not just about facades.
I received the following message while running tests using PHPUnit v.9.5.4, PHP v.8.0.3 and Lumen v. 8.2.2:
PHP Fatal error: Uncaught RuntimeException: A facade root has not
been set. in path_to_project/vendor/illuminate/support/Facades/Facade.php:258
And that happened although I had apparently already configured my app.php to enable facades ($app->withFacades();), still I received this error message whenever I tried to run tests using Illuminate\Support\Facades\DB. Unfortunately, none of the other answers helped me.
This error was actually been thrown due to my configs in phpunit.xml, which didn't point to my app.php file, where I actually enabled facades.
I just had to change
<phpunit (...OTHER_PARAMS_HERE) bootstrap="vendor/autoload.php">
to
<phpunit (...OTHER_PARAMS_HERE) bootstrap="bootstrap/app.php">
Hope it helps.
wrong way
public function register()
{
$this->app->bind('Activity', function($app)
{
new Activity;
});
}
right way 👍
public function register()
{
$this->app->bind('Activity', function($app)
{
return new Activity;
});
}
---------------------------------- don't forget return
Upgrade version for php, I encountered this error while calling the interface.
$ php artisan config:cache
Deleting the /bootstrap/cache/config.php file is a very effective way.
In my project, I managed to fix this issue by using Laravel Dependency Injection when instantiating the object. Previously I had it like this:
$class = new MyClass(
new Client(),
env('client_id', 'test'),
Config::get('myapp.client_secret')
);
The same error message happened when I used Laravel env() and Config().
I introduced the Client and env in the AppServiceProvider like this:
$this->app->bind(
MyClass::class,
function () {
return new MyClass(
new Client(),
env('client_id', 'test')),
Config::get('myapp.client_secret')
);
}
and then instantiated the class like this:
$class = app(MyClass::class);
See more from https://laravel.com/docs/5.8/container .
In my case, for a while a ran a PHP project in PHP version 8, and that time I used some PHP 8 features like param definition and method's multiple return type declarations supported by only PHP 8 and above. When I downgraded from PHP 8 to PHP 7.4 I faced this issue. After removing the return types and param hinting the problems are gone.
Tested on Laravel 8.78
tests/bootstrap.php
<?php
use Illuminate\Foundation\Bootstrap\RegisterFacades;
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
require_once __DIR__ . '/../vendor/autoload.php';
$app = require_once __DIR__ . '/../bootstrap/app.php';
(new LoadConfiguration())->bootstrap($app);// <------- Required for next line
(new RegisterFacades())->bootstrap($app);// <------- Add this line
Here is yet another instance of this error, happened to me after upgrading Laravel 8 to 9.
I had feature tests with a #dataProvider to supply data to those tests. Some of the data supplied by the data provider methods came from an application service. It was being initialised like this:
/**
* #dataProvider myDataProvider
*/
public function testSomeStuff(...)
{
...
}
public function myDataProvider()
{
$myService = app(Service::class); // This is trouble
return [
['test1_data' => $myService::SOME_CONSTANT],
[...],
...
];
}
This worked under Laravel 8, but not in Laravel 9. All other solutions listed in this SO thread were checked and were correctly set up.
The problem is that the application is not being inititialised until after the data provider method is run. It was presumably initialised before this stage in the Laravel 8 install. So app(Service::class) was failing due to it using facades internally.
One workaround could be to force the application to initialise earlier, in the data provider function: $this->createApplication(). I would not recommend this due to potential side effects of the test parts running in the wrong order, though it does appear to work when I tried it.
Best solution is to avoid accessing any part of the application functionality in the data provider methods. In my case it was easy to replace $myService::SOME_CONSTANT with MyService::SOME_CONSTANT after making sure those constants were public.
Hopefully this will help somebody suddenly hitting this problem running feature tests after a Laravel 9 upgrade.
If you recently upgrade Laravel on Homestead & VirtualBox environment or do not find any reason that causing please be sure your Vagrant is up to date.
Referance
I had Taylor lock this thread. The past several replies have restated the solution, which is to Upgrade to Virtualbox 6.x, the thread is locked to prevent other issues that are not related from being dogpiled on here.
#melvin's answer above works correctly.
In case someone is wondering about it, the mistake people do is to choose Yes when VSCode asks them if they are making a Unit Test. Remember, Unit Tests should really be unit tests, independent of other application features (models, factories, routes; basically anything that would require the Laravel app to be fired up). In most scenarios, people really actually want to make Feature Tests and therefore should answer No to the above question. A feature test inherits from Tests\TestCase class (which takes care of firing up Laravel app before running the test) unlike unit tests that inherit from the class PHPUnit\Framework\TestCase which use just PHPUnit and are therefore much faster.
credit with thanks to #Aken Roberts's answer here.
From Laravel Documentation: Generally, most of your tests should be feature tests. These types of tests provide the most confidence that your system as a whole is functioning as intended.

How to get PhpStorm to autocomplete facades in blade-files

When using #if (Auth::check()), PhpStorm doesn't recognize the Auth.
How do I tell PhpStorm that Auth is \Illuminate\Support\Facades\Auth?
Tested:
#php
use Illuminate\Support\Facades\Auth;
/** #var \Illuminate\Support\Facades\Auth Auth */
class Auth extends \Illuminate\Support\Facades\Auth {}
#endphp
#use(\Illuminate\Support\Facades\Auth)
neither worked, still get "Undefined Class Auth"
Edit 1:
the class Auth extends \Illuminate\Support\Facades\Auth {} line works if it's in another file, for example, the "_ide_helper.php", having it inside the blade file doesn't work.
IDE won't recognize methods accessed via the facade. laravel-ide-helper is a popular package that solves this problem. It generates a custom helper file that the IDE understands. This is not a complete solution but it covers most of laravel classes and helps with autocompletion. Here are your options.
Download and drop the latest _ide_helper.php file for laravel into your project from https://gist.github.com/barryvdh/5227822
Install the laravel-ide-helper package and let it generate a helper file on the fly. https://github.com/barryvdh/laravel-ide-helper
I'd personally suggest installing the package.
To get the right class use #if (\Auth::check())!

Call to undefined method Illuminate\View\View::make()

I am using Laravel 5.4.16 While using make method of View class i am getting undefined method error.
public function Index()
{
return View::make('stats');
}
Try to add this to the top of the class:
use View;
If it doesn't work then it looks like you didn't install the project. You need to run composer install or composer update command which will download and install all dependencies into the vendor directory.
Another thing to check is config/app.php should have this line:
'View' => Illuminate\Support\Facades\View::class,
Alternatively, you could use helper:
return view('stats');
But it will work only if porject is installed properly.
return view('path.to.your.directory');
You are receiving this error because make() method doesn't exist anywhere in your code. If you want to go from controller to view you can use simply:
public function Index() {
return view('stats');
}
It will go to your status blade view by accessing your url request.
Just use Facade instead. Check how it works and then check what is wrong with View first. And I hope you are not using another template engine as Twig for example, cause if yes then you have definitely use Facade or check how the View factory is working, I think it requires template engine in the constructor ...
Just use use Illuminate\Support\Facades\View;
You can try to use it:
return view('stats');

Laravel Controller not working

I'm very new to the Laravel framework and am trying to load a simple controller in my browser to slowly get the hang of things.
I have a file that's titled users.php inside of the the laravel/app/controllers/ folder and it looks like this:
class UsersController extends BaseController
{
public $restful = true;
public function action_index()
{
echo 'hi';
}
}
In the routes.php file, I have
Route::get('users', 'UsersController#index');
But, when I go to
http://localhost:8888/laravel/public/users
I'm greeted with a message that says "ReflectionException
Class UsersController does not exist"
I'm not sure if this is because I didn't install the mcrypt extension of PHP. But, when I checked the php.ini file on MAMP, it said that it was enabled. Upon entering
which PHP
in my terminal, it said /usr/bin/php. So, it might not be using the correct version of PHP.
I'm not entirely sure if this is a routes problem or if it's stemming from an absence of a vital PHP extension.
Thanks a bunch!
You need to use the Route::controller method to reference your Controller:
Route::controller('test', 'TestController');
...and rename your file (as Cryode mentions ) to be TestController.php.
Note - if you want to use the filename as test.php, then you will need to use composer to update the autoload settings.
Finally, the format of names for Controller methods changed in Laravel 4, try renaming the method
public function action_index() {}
to be
public function getIndex() {}
the get represents a HTTP GET request... the same applies for post (HTTP POST) and any (GET or POST.. )
I'm not familiar with that part of Laravel's source, so I'm not entirely certain that this is the issue, but your controller file name should match the controller class name, including capitalization.
So users.php should be UsersController.php. Now, when I do this myself on purpose, I get a "No such file or directory" error on an include() call, so that's why I'm not certain that's the sole cause of your problem. But it may be a start.

Resources