Laravel 5.4 - Basic Tests - NotFoundHttpException - php

I have a problem running the basic test that ships with Laravel:
app/tests/Feature/ExampleTest.php
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
$this->assertTrue(true);
}
}
When I run it I get the exception NotFoundHttpException. I can access my website in the browser without problems. This problem appears to apply to all my routes.
Using Laravel 5.4
The route / is defined in app/routes/web.php.

It seems that in Laravel 5.4 $baseUrl property was removed from TestCase class.
You may add some setUp to your ExampleTest:
function setUp()
{
parent::setUp();
config(['app.url' => 'https://myserver']);
}
Hope this helps!

Related

I am trying TDD(Test Driven Development) using Laravel8 inbuilt PHPUnit

I am receiving this error:
Call to undefined method Tests\Feature\ExampleTest::visit()
while running my test cases. I am a bit new to TDD.
Here is my ExampleTest Code
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function test_example()
{
$response = $this->visit('/')->see('Laravel');
$response->assertStatus(200);
}
}
From the video tutorial that I am using to learn about TDD the code above runs well without any issue but when it comes to running the code on my side I am faced with error as shown below :
• Tests\Feature\ExampleTest > example
Error
Call to undefined method Tests\Feature\ExampleTest::visit()
I am currently running Laravel 8.6 and PHPUnit 9.510
Any ideas on how I can resolve this are highly welcomed.
It looks like you are mixing up Laravel's built in browser testing methods (Dusk) - like visit() that you are using above - with the unit testing and feature testing methods.
As you are in the Tests\Feature namespace you need to follow the guide for unit and feature testing, the equivalent of which are:
public function test_example()
{
$response = $this->get('/');
$response->assertStatus(200);
}

Use Laravel Eloquent from within Behat/Mink FeatureContext

This question assumes some knowledge of Laravel, Behat, and Mink.
With that in mind, I am having trouble making a simple call to the DB from within my Behat FeatureContext file which looks somewhat like this...
<?php
use App\Models\Db\User;
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;
/**
* Defines application features from the specific context.
*/
class FeatureContext extends MinkContext implements Context {
public function __construct() {}
/**
* #Given I am authenticated with :email and :password
*/
public function iAmAuthenticatedWith($email, $password) {
User::where('email', $email)->firstOrFail();
$this->visitPath('/login');
$this->fillField('email', $email);
$this->fillField('password', $password);
$this->pressButton('Login');
}
}
When this scenario runs I get this error...
Fatal error: Call to a member function connection() on null (Behat\Testwork\Call\Exception\FatalThrowableError)
Which is caused by this line...
User::where('email', $email)->firstOrFail();
How do I use Laravel Eloquent (make DB calls) from within a Behat/Mink FeatureContext? Do I need to expose something within the constructor of my FeatureContext? Update/add a line within composer.json or behat.yml file?
If there is more than one way to solve this problem and it is worth mentioning, please do.
Additional Details
Laravel: 5.5.*
Behat: ^3.3
Mink Extension: ^2.2
Mink Selenium 2 Driver: ^1.3
Behat Config
default:
extensions:
Behat\MinkExtension\ServiceContainer\MinkExtension:
base_url: "" #omitted
default_session: selenium2
selenium2:
browser: chrome
Laravel need to setup the eloquent and the connection for this to work.
The easy way is to extend laravel TestCase and in the __constructor() call parent::setUp();
It will setup your test environment, like it does when you run php test units in Laravel:
/**
* Setup the test environment.
*
* #return void
*/
protected function setUp()
{
if (! $this->app) {
$this->refreshApplication();
}
$this->setUpTraits();
foreach ($this->afterApplicationCreatedCallbacks as $callback) {
call_user_func($callback);
}
Facade::clearResolvedInstances();
Model::setEventDispatcher($this->app['events']);
$this->setUpHasRun = true;
}
The refreshApplication() will call the createApplication() and it does bootstrap the Laravel and create the $this->app object.
/**
* Refresh the application instance.
*
* #return void
*/
protected function refreshApplication()
{
$this->app = $this->createApplication();
}

Registering a custom controller class in Laravel

I have this this class that is a ServiceProvider
namespace Package\Avatar;
use Illuminate\Support\ServiceProvider;
class AvatarServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
include __DIR__.'/routes.php';
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
try{
$this->app->make('Package\Avatar\AvatarController');
} catch (\Exception $e){
dd($e);
}
}
}
But when I try to access to some url of AvatarCotroller class the screen is Blank, and no show neither error. But whenever I comment this line
$this->app->make('Package\Avatar\AvatarController');
I can get the normal errors of Laravel.
You can get rid of including the routes.php in the boot method of the service provider. Simply use $this->app->call('Package\Avatar\AvatarController#method') to call the method on the controller
try
php artisan optimize : to reuse all frequently used classes php will make an cached class in cache/service.php. So we if add new service we need to run it. We need to use it whenever we add new dependency without using composer.
php artisan cache:clear : clear all the above cache and remap everything

Bind interface to implementation - target not instantiable when using the $defer property

I've bound an interface to its implementation, like this:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\Mail\Contracts\Webhook;
use App\Services\Mail\Clients\MailgunWebhook;
class MailServiceProvider extends ServiceProvider {
protected $defer = true;
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot() {
//
}
/**
* Register the application services.
*
* #return void
*/
public function register() {
$this->app->bind(
Webhook::class,
MailgunWebhook::class
);
}
}
I ran all of these:
php artisan config:clear
php artisan clear-compiled
php artisan optimize
composer dumpautoload
Yet, I still got the "Target is not instantiable error", when trying to use the binding.
After I commented out the $defer property, the binding started to work.
Why can't I use $defer in this case?
As stated in the documentation, to which I linked myself and failed to read it in full, $defer needs the provides() method.
In my case, all I needed to add in my service provider class is this:
public function provides() {
return array(Webhook::class);
}
Thanks to James Fenwick for his comment.

PHPUnit_Framework_TestCase Found but undefined method ::call()

Hi i am working with Laravel 4.2.17 , PHPUnit 5.1.1 and PHP 5.6.16 .
I am using PHPStorm as My Editor .
When i go to app/tests/ExampleTest.php and run it i am getting the error .
PHP Fatal error: Class 'TestCase' not found in /..../app/tests/ExampleTest.php on line 3
Then i changed TestCase to PHPUnit_Framework_TestCase Now the ExampleTest.php looks like this
class ExampleTest extends PHPUnit_Framework_TestCase {
/**
* A basic functional test example.
*
* #return void
*/
public function testBasicExample()
{
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
}
}
Now the PHPUnit_Framework_TestCase calls is identified .
But when i try to do
public function testBasicExample()
{
$this->call("POST","test");
}
It is saying that
Fatal error: Call to undefined method ExampleTest::call()
I checked the larval documents and in there
Calling A Route From A Test
You may easily call one of your routes for a test using the call method:
$response = $this->call('GET', 'user/profile');
$response = $this->call($method, $uri, $parameters, $files, $server, $content);
SO i am not sure what i am doing wrong .
I also tried by updating the composer , but no luck . :( :(
The reason you cannot access call is because you are no longer extending TestCase which provides it. I suggest you revert back to extends TestCase and run your tests again. You should make sure to run the test from the root directory by using phpunit app/tests.
Running composer dump-autoload also first, just in case it's an autoloading issue.

Categories