Closed KarimGeiger closed 9 years ago
Changing the setUp method to use createApplication each time fixed this for me.
public function setUp()
{
parent::setUp();
$this->createApplication();
$this->artisanMigrateRefresh();
}
Hope this helps!
@benjaminkimball: Thanks for the reply. Sadly, that did not fix it for me. You can verify it by checking out my example project.
@GrahamCampbell: please reopen the ticket, since it's not fixed.
@KarimGeiger Sorry, should have mentioned that you should move the setUp to the base TestCase!
<?php
use Illuminate\Support\Facades\Artisan as Artisan;
class TestCase extends Laravel\Lumen\Testing\TestCase {
/**
* Creates the application.
*
* @return \Laravel\Lumen\Application
*/
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
public function setUp()
{
parent::setUp();
$this->createApplication();
$this->artisanMigrateRefresh();
}
public function tearDown()
{
$this->artisanMigrateReset();
parent::tearDown();
}
protected function artisanMigrateRefresh()
{
Artisan::call('migrate');
}
protected function artisanMigrateReset()
{
Artisan::call('migrate:reset');
}
}
I just confirmed this with your test repo!
Yes, this kind of works, but it won't recreate the database for each test. So if you're trying to test accessing a table, you'll get the following message:
lumen.ERROR: exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 1 no such table: users'
I've updated the repo to reproduce this state.
Ah, I see. I'm getting the same error with your test repo. I can't get the DB facade to play nice either. I'm using Eloquent in my project and it's working just fine. I'll try switching one of my controllers over to straight DB and see what happens.
Sure enough. Switching to not use Eloquent broke my tests as well. I'm at a loss for now!
Glad I'm not alone with that. And thanks for helping :) Hope we'll find a solution soon.. I'm out of guesses.
Looked to see if your test repo was still there. I've updated my TestCase to the following and seen better results all around with my tests! Give it a shot!
<?php
use Illuminate\Support\Facades\Artisan as Artisan;
class TestCase extends Laravel\Lumen\Testing\TestCase {
/**
* Creates the application.
*
* @return \Laravel\Lumen\Application
*/
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
public function setUp()
{
parent::setUp();
$this->refreshApplication();
$this->artisan('migrate');
}
public function tearDown()
{
$this->artisan('migrate:reset');
parent::tearDown();
}
}
Thanks a lot, this seems to work now exactly as expected!
Sweet!
The facades are the problem. Disable facades.
@neylsongularte , Dont you think its bit stupid solution? :) I mean disable facades? seriously?! And solutions listed here does'not work for me!
Work for me as a palliative solution.
I have a same issue here, using lumen version 5.0.10, unit test only work if i run each test, when i run all tests, then triggered ReflectionException which said "Class config doesnt exists". I have done "composer dump-autoload" and use "$this->refreshApplication" in my TestCase class, but still not work
@KarimGeiger hello, are you sure that all of your tests is working now? which lumen version you used?
@hiraq yes, they all do. My TestCase currently looks like this:
<?php
use Illuminate\Support\Facades\Artisan as Artisan;
class TestCase extends Laravel\Lumen\Testing\TestCase
{
/**
* Creates the application.
*
* @return \Laravel\Lumen\Application
*/
public function createApplication()
{
return require __DIR__ . '/../bootstrap/app.php';
}
public function setUp()
{
parent::setUp();
$this->createApplication();
$this->artisanMigrateRefresh();
}
protected function artisanMigrateRefresh()
{
Artisan::call('migrate');
Artisan::call('db:seed');
}
}
In the test itself I'm just extending TestCase, not defining setUp()
or anything else.
Unfortunately, if i used $this->createApplication then it will throw another error, when i use $this->call inside my test, it will not send all parameters to controller
and if i used $this->refreshApplication, it just works for first test, the other tests will failed
what version you used @KarimGeiger ?
I just updated everything using composer, the tests are still working:
laravel/lumen-framework v5.0.10
phpunit/phpunit 4.6.9
In /bootstrap/app.php
I've enabled both Facades and Eloquent:
$app->withFacades();
$app->withEloquent();
Here my test case
<?php
use App\Models\User;
use App\Models\Observers\User as UserObserver;
class UsersControllerTest extends TestCase {
public function testRegisterSuccess()
{
$params = [
'email' => 'test@test.com',
'password' => 'testing',
'password_confirmation' => 'testing'
];
$response = $this->call('POST', '/api/v1/users/register', $params);
$json = json_decode($response->getContent());
$this->assertResponseOk();
/*
* check and test json response
*/
$this->assertTrue(isset($json->status));
$this->assertTrue(isset($json->data));
$this->assertEquals('success', $json->status);
$this->assertTrue(empty($json->data));
/*
* check and test database data
*/
$user = User::where('email', 'test@test.com')->first();
$this->assertTrue(!empty($user));
$this->assertTrue(isset($user->email));
$this->assertEquals('test@test.com', $user->email);
}
public function testRegisterFailedEmailExists()
{
$this->generateUser('test@test.com', 'testing');
$params = [
'email' => 'test@test.com',
'password' => 'testing',
'password_confirmation' => 'testing'
];
$response = $this->call('POST', '/api/v1/users/register', $params);
$this->assertResponseStatus(400);
$json = json_decode($response->getContent());
$this->assertTrue(isset($json->status));
$this->assertEquals('error', $json->status);
$this->assertTrue(isset($json->message));
$this->assertEquals('Fail to validate.', $json->message);
}
private function generateUser($email, $password)
{
User::observe(new UserObserver);
$user = new User;
$user->register($email, $password);
}
}
and here my TestCase class:
<?php
use Illuminate\Support\Facades\Artisan;
use App\Models\User;
class TestCase extends Laravel\Lumen\Testing\TestCase {
/**
* Creates the application.
*
* @return \Laravel\Lumen\Application
*/
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
public function setUp()
{
parent::setUp();
$this->refreshApplication();
Artisan::call('migrate');
}
public function tearDown()
{
Artisan::call('migrate:reset');
}
}
Here my screenshot if run my tests one by one
I cannot use :
$this->createApplication()
Because i can't send my POST parameters (and i dont know why too), so i use :
$this->refreshApplication()
Ok, it works now, in my case it's caused by :
parent::tearDown()
It looks strange here, when i put that code inside my TestCase class (or anyelse) at "tearDown" method, then all tests broke with ReflectionException error Class config doesn't exists
yeah but thank you guys for your help, at least my tests works now :smile:
What you need to do is add this in setUp()
public function setUp()
{
parent::setUp();
\Illuminate\Support\Facades\Facade::clearResolvedInstances();
}
This has been fixed in commit c5d599b086f20a6c0db69ba6ff1f00999ef68654
I was using laravel, but maybe it could be helpfull. I've rewritted my tearsDown method, exactly like the original, but removing the flush part, so my tearsDown method is like that:
`if ($this->app) { foreach ($this->beforeApplicationDestroyedCallbacks as $callback) { call_user_func($callback); }
//$this->app->flush(); removed
//$this->app = null; removed
}
if (property_exists($this, 'serverVariables')) {
$this->serverVariables = [];
}
if (class_exists('Mockery')) {
Mockery::close();
}`
Getting exactly the same issue - here's a little more info.
My tests have a setup and teardown method
public function setUp()
{
parent::setUp();
//Small couple of lines of my code.
}
public function tearDown()
{
parent::tearDown();
}
When my tests run, even though they all pass, I'm left with this as an error message at the end:
PHPUnit 5.0.10 by Sebastian Bergmann and contributors.
Time: 6.36 seconds, Memory: 24.00Mb
OK (2 tests, 2 assertions)
Fatal error: Uncaught ReflectionException: Class config does not exist in /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 749
Call Stack:
0.0663 788384 1. {main}() /home/vagrant/Code/SourcePhars/phpunit.phar:0
0.8682 7918344 2. PHPUnit_TextUI_Command::main() /home/vagrant/Code/SourcePhars/phpunit.phar:513
0.8682 7918456 3. PHPUnit_TextUI_Command->run() phar:///home/vagrant/Code/SourcePhars/phpunit.phar/phpunit/TextUI/Command.php:105
ReflectionException: Class config does not exist in /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 749
Call Stack:
0.0663 788384 1. {main}() /home/vagrant/Code/SourcePhars/phpunit.phar:0
0.8682 7918344 2. PHPUnit_TextUI_Command::main() /home/vagrant/Code/SourcePhars/phpunit.phar:513
0.8682 7918456 3. PHPUnit_TextUI_Command->run() phar:///home/vagrant/Code/SourcePhars/phpunit.phar/phpunit/TextUI/Command.php:105
6.3677 22266048 4. App\Service\HeatTimer\HeatTimer->__destruct() /home/vagrant/Code/demo.local.test/app/Service/HeatTimer/HeatTimer.php:0
6.3677 22266048 5. App\Service\HeatTimer\HeatTimer->logout() /home/vagrant/Code/demo.local.test/app/Service/HeatTimer/HeatTimer.php:276
6.3677 22266048 6. config() /home/vagrant/Code/demo.local.test/app/Service/HeatTimer/HeatTimer.php:287
6.3677 22266048 7. app() /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:263
6.3677 22266104 8. Illuminate\Foundation\Application->make() /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:106
6.3677 22266104 9. Illuminate\Container\Container->make() /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:709
6.3678 22266104 10. Illuminate\Container\Container->build() /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php:644
6.3678 22266216 11. ReflectionClass->__construct() /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php:749
PHP Fatal error: Uncaught ReflectionException: Class config does not exist in /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php:749
Stack trace:
#0 /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php(749): ReflectionClass->__construct('config')
#1 /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php(644): Illuminate\Container\Container->build('config', Array)
#2 /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(709): Illuminate\Container\Container->make('config', Array)
#3 /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(106): Illuminate\Foundation\Application->make('config', Array)
#4 /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(263): app('config')
#5 /home/vagrant/Code/demo.local.test/app/Service/HeatTimer/HeatTimer.php(287): config( in /home/vagrant/Code/demo.local.test/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 749
PHP Stack trace:
PHP 1. {main}() /home/vagrant/Code/SourcePhars/phpunit.phar:0
PHP 2. PHPUnit_TextUI_Command::main() /home/vagrant/Code/SourcePhars/phpunit.phar:513
PHP 3. PHPUnit_TextUI_Command->run() phar:///home/vagrant/Code/SourcePhars/phpunit.phar/phpunit/TextUI/Command.php:105
Process finished with exit code 255
After some digging around the tearDown
method, I went up the tree and finally found the line that was causing the issue.
A normal test calls parent::tearDown
which is \Illuminate\Foundation\Testing\TestCase.php
This calls $this->app->flush();
which is in \Illuminate\Foundation\Application.php
Which calls it's parent parent::flush
which is in Illuminate\Container\Container.php
Which finally runs this code:
/**
* Flush the container of all bindings and resolved instances.
*
* @return void
*/
public function flush()
{
$this->aliases = [];
$this->resolved = [];
$this->bindings = [];
$this->instances = [];
}
If I comment out
$this->instances = [];
Everything works perfectly and there are no more error messages.
Does that help anyone explain these? I'm out of my depth.
Thanks.
Nothing works for me. Magic, magic, magic.
[Using Laravel] I forgot to add parent::setUp();
in my setUp() method and was getting this error. After adding it, everything worked fine for me.
Damn, this project management looks really idiotic. No one reported that the issue is resolved, but the admin is closing every thread how he like. It's not democratic, it's boorish.
@blackness90 I faced to a similar issue. Lumen 5.4. unit test but without migrations.
using Config::set('key', 'value')
was not worked. So I had to use this way.
//test
use Illuminate\Support\Facades\Config;
Config::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
//code
use Illuminate\Support\Facades\Config;
Config::get('key');
//instead config('key');
I was running into a similar problem when running PHPUnit 7.5 tests with Laravel Lumen 5.4, which was solved by Benjamin Kimball's solution to add or move the setUp() method to the base TestCase class.
The error message I was getting was "ReflectionException: Class config does not exist" when running PHPUnit:
All of the values in my .env
were properly quoted, but the following changes to tests/TestCase.php
fixed the issue:
<?php
abstract class TestCase extends Laravel\Lumen\Testing\TestCase
{
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
public function setUp()
{
parent::setUp();
$this->createApplication();
}
}
I'm trying to setup unit tests for my Lumen application. Sadly, that only works well for the first test. So I'm assuming Lumen doesn't refresh correctly. Have a look at my TestCase class:
When running a test, I'm setting up the database using:
This works well for the first test. The second test fails, saying "ReflectionException: Class config does not exist" (Full error trace).
I've tried loading Lumen once for all tests (just for clarification), and that kind of worked, but as you may have guessed it just made things worse.
The migration (and call) itself works.. I've adjusted the phpunit.xml to use a sqlite memory-database:
To reproduce this behaviour, have a look at my test repository. Just check it out, run composer update and then run phpunit. You will see the test failing. Remove the second test at tests/ExampleTest.php, run phpunit again and it will succeed.
Things I've done:
(See the forum post for additional information)