Using class constants in PHPUnit annotations - php

The manual of PHPUnit shows, that I can use class-constants in annotations for #expectedExceptionCode, see PHPUnit #expectedExceptionCode
I try to use it within my name spaced model which extends from Eloquent.
When I run my tests I got an: "PHP Fatal error: Class 'Eloquent' not found"
Running the App is all fine, so it depends on the Unit-Tests, isn't it?
Any ideas?
namespace Foo\Models;
use \Eloquent;
class Bar extends Eloquent {
const ERRORCODE = 150;
...
}
class BarTest extends TestCase {
/**
* #expectedExceptionCode Foo\Models\Bar::ERRORCODE
*/
public function testFoobar()
{
$name = 'foobar';
Bar::findBarOrFail($name);
}
}
For clarification:
PHP Fatal error: Class 'Eloquent' not found in PathToProject/app/models/Bar.php
Update
After #j-boschieros comment I got the above code working! Thanks mate!
However, when I provoke the exception in a controller test, the fatal error still occurs.
Even if I use the namespaces or not.
use \Eleoquent;
use Foo\Models\Bar;
class TestController extends TestCase {
/**
* #expectedExceptionCode Foo\Models\Bar::ERRORCODE
*/
public function testStoreActionWithInvalidDatatyp ()
{
$this->call('POST', '/routeToException');
}
Update 2
Got my Unit-Tests working when I extend \Illuminate\Database\Eloquent\Model instead of Eloquent.
namespace Foo\Models;
use \Illuminate\Database\Eloquent\Model;
class Bar extends Model {
const ERRORCODE = 150;
...
}
This differs from Laravel Doc. Is it still okay?

The "class" \Eloquent is actually an alias which is registered at run-time by the Laravel framework. You're making PHP parse the model class file before these aliases have been set up, causing it to fail. The correct approach to this is just to avoid the global namespace aliases and use the real class names instead (Illuminate\Database\Eloquent\Model instead of Eloquent in your case). You can find a list of class aliases in app/config/app.php.

Related

Dynamically Initiate a class in another's constructor in Laravel (or php)

To make it simple i have two classes:
class AddressController extends ApiController
{
private AddressRepository $addressRepository;
public function __construct(AddressRepository $addressRepository)
{
$this->addressRepository = $addressRepository;
}
//........
class CountyController extends ApiController
{
private CountyRepository $countyRepository;
public function __construct(CountyRepository $countyRepository)
{
$this->countyRepository = $countyRepository;
}
//........
As you can see I'm extending the ApiController class and use dependency injection for both (county/address) repository.
My question is how to refactor it in a away everytime i extend from the ApiController, it create the repository property with the proper namespace.
Hi I suggest to do some tweaks on your Laravel Stub, which can fulfill your requirement.
On publishing Laravel Controller from command, you can customize your namespace and the stuffs you require in controller.
You can publish your current stub file using artisan command
php artisan stub:publish
for more https://laravel-news.com/customizing-stubs-in-laravel

Laravel Database Factory Files not being called

I'm trying to test a model I've created, and I'm getting the error:
InvalidArgumentException: Unable to locate factory with name [default]
[App\Company].
Here's what my very simple model looks like:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Company extends Model
{
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function incidents()
{
return $this->hasMany(Incident::class);
}
}
here's the factory:
<?php
$factory->define(\App\Company::class, function () {
return [
'name' => 'ACME Company'
];
});
and the setup method in my unit test that's throwing the error:
<?php
use Illuminate\Foundation\Testing\DatabaseMigrations;
class CompanyModelTest extends TestCase
{
use DatabaseMigrations;
public function setUp()
{
factory(\App\Company::class)->create();
}
When I run the test I get this:
laradock#63912b4222e6:/var/www/laravel$ vendor/bin/phpunit
PHPUnit 5.5.6 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 528 ms, Memory: 4.00MB
There was 1 error:
1) CompanyModelTest::testCompanyName
InvalidArgumentException: Unable to locate factory with name [default] [App\Company].
/var/www/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:126
/var/www/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2280
/var/www/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:139
/var/www/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:106
/var/www/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:84
/var/www/laravel/tests/CompanyModelTest.php:13
So far I've tried the suggestions on this other Stackoverflow question about the same error, and also this one.
I've tried moving my new factory into the ModelFactory.php file that's there by default and I've tried using defineAs() instead of define.
I've cleared the cache and run composer dump-autoload as suggested in other posts around the web.
I've dumped out the contents of FactoryBuilder::definitions which is empty, and that's what's causing the exception to be thrown.
I've confirmed that none of the factory files in database\factories directory are being called with debug code & a line that would cause a parse error.
Why aren't those files being called as per the documentation?
In my situation the TestCase was wrong class.
class CompanyModelTest extends TestCase
Which TestCase do you extend? I had
use PHPUnit\Framework\TestCase;
Instead of Laravel's own. Now it is working!
use Tests\TestCase;
Make sure you extend the correct TestCase class.

Laravel 5 Tinker eval() error

I'm trying to test my model relations using tinker but they're all giving errors
This is the code I'm trying
$event = \App\Event::all();
This is the error
PHP Fatal error: Call to undefined method App\Event::all() in
D:\Sites\nightshift2015\vendor\psy\psy
I have tried without the first \ but it's giving the same error
$event = App\Event::all();
This is my Event class
<?php namespace App;
class Event {
public function exhibitors() {
return $this->hasMany('App\Exhibitor');
}
public function conference() {
return $this->hasOne('App\Conference');
}
}
If that’s your event class, then it’s not extending Laravel’s base Model class, therefore hasn’t inherited any of its methods.
Fix it by changing it to this:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model {

Extend Laravel 4.1 validation class

I try extend Validator class. I need add a few methods, that I'd like extend all class not use Validator::extend();
I added in vendor direcotry structure:
-comjaroapp
-src
-Comjaroapp
-Validation
-Validator.php
-ValidatorServiceProvider.php
In my config/app.php in providers array, I added:
'Comjaroapp\Validation\ValidatorServiceProvider'
Code to test is simple:
Validator:
namespace Comjaroapp\Validation;
class CustomValidator extends \Illuminate\Validation\Validator{
public function validatePesel($attribute,$value,$options=null){
return true;
}
}
ValidatorServiceProvider:
namespace Comjarospp\Validation;
use Illuminate\Support\ServiceProvider;
class ValidatorServiceProvider extends ServiceProvider{
public function register(){}
public function boot(){
$this->app->validator->resolver(function($transator,$data,$rules,$messages){
return new CustomValidator($transator,$data,$rules,$messages);
});
}
}
After run composer update I see error:
> Error Output: PHP Fatal error: Class
> 'Comjaroapp\Validation\ValidatorServiceProvider' not found in
> /vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php
> on line 158
When I looked on other extension all work with same structure.
If someone have idea, what is wrong or when should I search, please help.
Thanks in advance.
You have different names for your namespaces:
Comjarospp\Validation
and
Comjaroapp\Validation
EDIT:
After fixing the namespace name, have you executed
composer dumpautoload
?

Error extending Laravel's abstract TestCase class (error is saying that my extended class must be abstract)

I'm hoping somebody out there can help me. I am using laravel 4 and I'm writing my first unit tests for a while but am running into trouble. I'm trying to extend the TestCase class but I'm getting the following error:
PHP Fatal error: Class registrationTest contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Illuminate\Foundation\Testing\TestCase::createApplication) in /home/john/www/projects/MyPainChart.com/app/tests/registrationTest.php on line 4
Now if I have this right then the error is referring to the fact that is a method is abstract then the class it's in must also be abstract. As you can see from below the TestCase class it is abstract. I have searched for this error but have drawn a blank.
Trying to follow this cast on Laracasts https://laracasts.com/lessons/tdd-by-example and although you have to be a subscriber to watch the video the file is underneath it and as you can see I am doing nothing different to Jeffrey Way.
My Test:
<?php
class registrationTests extends \Illuminate\Foundation\Testing\TestCase
{
/**
* Make sure the registration page loads
* #test
*/
public function make_sure_the_registration_page_loads_ok()
{
$this->assertTrue(true);
}
}
The beginning of the TestCase class:
<?php namespace Illuminate\Foundation\Testing;
use Illuminate\View\View;
use Illuminate\Auth\UserInterface;
abstract class TestCase extends \PHPUnit_Framework_TestCase {
By the way - the Laravel testing class is not autoloaded by default and so I have tried both the fully qualified class name and use Illuminate\Foundation\Testing and then just extending TestCase. I know it can see it aswhen I don't fully qualify the name it complains that the class cannot be found. I've also tried:
composer dump-autoload
and
composer update
Any help appreciated
According to your error message: Class registrationTest contains 1 abstract method the Base Class contains an abstract method and when a Child Class extends another class with abstract methods then the child class should implement the abstract methods available in Base class. So, registrationTest is child class and \Illuminate\Foundation\Testing\TestCase is the base class and it contains an abstract method:
An abstract method in \Illuminate\Foundation\Testing\TestCase:
abstract public function createApplication();
So, in your child class/registrationTest you must implement this method:
public function createApplication(){
//...
}
But, actually you don't need to directly extend the \Illuminate\Foundation\Testing\TestCase because in app/tests folder there is a class TestCase/TestCase.php and you can extend this class instead:
// In app/tests folder
class registrationTest extends TestCase {
//...
}
The TestCase.php class looks like this:
class TestCase extends Illuminate\Foundation\Testing\TestCase {
public function createApplication()
{
$unitTesting = true;
$testEnvironment = 'testing';
return require __DIR__.'/../../bootstrap/start.php';
}
}
Notice that, TestCase has implemented that abstract method createApplication so you don't need to extend it in your class. You should use TestCase class as base class to create test cases. So, create your tests in app/tests folder and create classes like:
class registrationTest extends TestCase {
public function testBasicExample()
{
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
}
}
Read Class Abstraction.
Firstly go in composer.json and add
"scripts" : {"test" : "vendor/bin/phpunit"
}
Then run composer update
Then
The TestCase.php class in path /test/ should look like
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Artisan;
abstract class TestCase extends BaseTestCase {
use CreatesApplication;
}
Then your registrationTests class should look like this
<?php
namespace Tests\Feature;
use Tests\TestCase;
class registrationTests extends TestCase {}
Just intake dependancy at the top of your class as follows and you are good to go,
<?php
namespace YOUR_CLASS_PATH;
use Tests\TestCase;
class UserTest extends TestCase{
...//your business logic here
}
I hope this works.

Categories