如何在Workbench中测试Eloquent?

时间:2013-11-10 23:42:11

标签: unit-testing laravel laravel-4

编辑:1

我需要通过触摸数据库测试一个Eloquent模型,我有这个测试用例:

use Mockery as m;

use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\ConnectionResolver;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Artisan;
use Illuminate\Container\Container;
use Illuminate\Config\Repository as Config;
use Illuminate\Database\Console\Migrations\MigrateCommand;
use Illuminate\Database\Migrations\Migrator;
use Illuminate\Database\Migrations\DatabaseMigrationRepository;
use Illuminate\Filesystem\Filesystem;

class Module extends Eloquent {

    protected $table = 'modules';
    protected $fillable = array('name');

}

class UserTest extends PHPUnit_Framework_TestCase{

    public function setUp()
    {   
        $this->modelName = 'My Model Name';

        $this->migrationsTable = 'migrations';

        $this->environment = 'testing';

        $this->connectionName = 'postgresql'; // postgresql memory

        date_default_timezone_set('UTC');

        $this->app = new Application;

        $this->migrationPath = __DIR__ . '/../../migrations';

        $this->app->instance('path', __DIR__);

        $this->app->instance('config', $config = new Config(

            $this->app->getConfigLoader(), $this->environment

        ));

        $this->app['config']['app'] = array(    'debug' => true,
                                                'url' => 'http://localhost',
                                                'timezone' => 'UTC',
                                                'locale' => 'en',
                                                'key' => 'YourSecretKey!!!',

                                                'providers' => array(
                                                    'Illuminate\Foundation\Providers\ArtisanServiceProvider',
                                                    'Illuminate\Auth\AuthServiceProvider',
                                                    'Illuminate\Cache\CacheServiceProvider',
                                                    'Illuminate\Session\CommandsServiceProvider',
                                                    'Illuminate\Foundation\Providers\ConsoleSupportServiceProvider',
                                                    'Illuminate\Routing\ControllerServiceProvider',
                                                    'Illuminate\Cookie\CookieServiceProvider',
                                                    'Illuminate\Database\DatabaseServiceProvider',
                                                    'Illuminate\Encryption\EncryptionServiceProvider',
                                                    'Illuminate\Filesystem\FilesystemServiceProvider',
                                                    'Illuminate\Hashing\HashServiceProvider',
                                                    'Illuminate\Html\HtmlServiceProvider',
                                                    'Illuminate\Log\LogServiceProvider',
                                                    'Illuminate\Mail\MailServiceProvider',
                                                    'Illuminate\Database\MigrationServiceProvider',
                                                    'Illuminate\Pagination\PaginationServiceProvider',
                                                    'Illuminate\Queue\QueueServiceProvider',
                                                    'Illuminate\Redis\RedisServiceProvider',
                                                    'Illuminate\Remote\RemoteServiceProvider',
                                                    'Illuminate\Auth\Reminders\ReminderServiceProvider',
                                                    'Illuminate\Database\SeedServiceProvider',
                                                    'Illuminate\Session\SessionServiceProvider',
                                                    'Illuminate\Translation\TranslationServiceProvider',
                                                    'Illuminate\Validation\ValidationServiceProvider',
                                                    'Illuminate\View\ViewServiceProvider',
                                                    'Illuminate\Workbench\WorkbenchServiceProvider',
                                                ),

                                                'manifest' => '/meta',

                                                'aliases' => array(
                                                    'App'             => 'Illuminate\Support\Facades\App',
                                                    'Artisan'         => 'Illuminate\Support\Facades\Artisan',
                                                    'Auth'            => 'Illuminate\Support\Facades\Auth',
                                                    'Blade'           => 'Illuminate\Support\Facades\Blade',
                                                    'Cache'           => 'Illuminate\Support\Facades\Cache',
                                                    'ClassLoader'     => 'Illuminate\Support\ClassLoader',
                                                    'Config'          => 'Illuminate\Support\Facades\Config',
                                                    'Controller'      => 'Illuminate\Routing\Controller',
                                                    'Cookie'          => 'Illuminate\Support\Facades\Cookie',
                                                    'Crypt'           => 'Illuminate\Support\Facades\Crypt',
                                                    'DB'              => 'Illuminate\Support\Facades\DB',
                                                    'Eloquent'        => 'Illuminate\Database\Eloquent\Model',
                                                    'Event'           => 'Illuminate\Support\Facades\Event',
                                                    'File'            => 'Illuminate\Support\Facades\File',
                                                    'Form'            => 'Illuminate\Support\Facades\Form',
                                                    'Hash'            => 'Illuminate\Support\Facades\Hash',
                                                    'HTML'            => 'Illuminate\Support\Facades\HTML',
                                                    'Input'           => 'Illuminate\Support\Facades\Input',
                                                    'Lang'            => 'Illuminate\Support\Facades\Lang',
                                                    'Log'             => 'Illuminate\Support\Facades\Log',
                                                    'Mail'            => 'Illuminate\Support\Facades\Mail',
                                                    'Paginator'       => 'Illuminate\Support\Facades\Paginator',
                                                    'Password'        => 'Illuminate\Support\Facades\Password',
                                                    'Queue'           => 'Illuminate\Support\Facades\Queue',
                                                    'Redirect'        => 'Illuminate\Support\Facades\Redirect',
                                                    'Redis'           => 'Illuminate\Support\Facades\Redis',
                                                    'Request'         => 'Illuminate\Support\Facades\Request',
                                                    'Response'        => 'Illuminate\Support\Facades\Response',
                                                    'Route'           => 'Illuminate\Support\Facades\Route',
                                                    'Schema'          => 'Illuminate\Support\Facades\Schema',
                                                    'Seeder'          => 'Illuminate\Database\Seeder',
                                                    'Session'         => 'Illuminate\Support\Facades\Session',
                                                    'SSH'             => 'Illuminate\Support\Facades\SSH',
                                                    'Str'             => 'Illuminate\Support\Str',
                                                    'URL'             => 'Illuminate\Support\Facades\URL',
                                                    'Validator'       => 'Illuminate\Support\Facades\Validator',
                                                    'View'            => 'Illuminate\Support\Facades\View',
                                                ),

                                            );

        $this->app['config']['database'] = array('connections' => array(
                                                                            'memory' => array(
                                                                                'driver'   => 'sqlite',
                                                                                'database' => ':memory:',
                                                                                'prefix'   => ''
                                                                                ),

                                                                            'postgresql' => array(
                                                                                'driver'   => 'pgsql',
                                                                                'host'     => 'localhost',
                                                                                'database' => 'antoniocarlosribeiro',
                                                                                'username' => 'antoniocarlos',
                                                                                'password' => 'basswort',
                                                                                'charset'  => 'utf8',
                                                                                'prefix'   => '',
                                                                                'schema'   => 'public',
                                                                            ),

                                                                        )
                                                  );

        $this->factory = new ConnectionFactory($this->app);

        $this->manager = new DatabaseManager($this->app, $this->factory);

        $this->migrateCommand = new MigrateCommand(
                                    new Migrator(
                                        new DatabaseMigrationRepository(
                                                $this->manager, 
                                                $this->migrationsTable
                                            ), 
                                        $this->manager, 
                                        new Filesystem
                                    ), 
                                    $this->migrationPath
                                );

        $this->model = new Module;

        $this->model->setConnectionResolver($this->manager);

        $this->model->setConnection($this->connectionName);

        // $this->app->instance('artisan', $artisan = new Artisan($this->app));
        // $this->app['artisan']->add($this->migrateCommand);
        // $this->app['artisan']->call('migrate:refresh');
    }

    public function tearDown()
    {
        m::close();
    }

    public function testCreated()
    {
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Model', $this->model);
    }   

    public function testDeleteCreateSelect()
    {
        $this->model->on($this->connectionName)->where('name', $this->modelName)->delete();

        $this->model->on($this->connectionName)->insert( array('name' => $this->modelName, 'created_at' => new DateTime, 'updated_at' => new DateTime) );

        $this->assertEquals($this->model->where('name', $this->modelName)->first()->name, $this->modelName);
    }   
}

这件事情很好。删除,插入和选择正在工作并点击数据库,所以我得到一个绿色。

我计划在数据库上开发测试,看看数据,然后转移到:memory:,以提高速度。

现在的问题是我需要Artisan工作,所以我可以migrate:refresh每次运行,但是如果我启用这3个工匠线,那就归结为对工匠的递归调用:

    PHP   1. {main}() /usr/share/phpunit/vendor/phpunit/phpunit/composer/bin/phpunit:0
    PHP   2. PHPUnit_TextUI_Command::main() /usr/share/phpunit/vendor/phpunit/phpunit/composer/bin/phpunit:63
    PHP   3. PHPUnit_TextUI_Command->run() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:129
    PHP   4. PHPUnit_TextUI_TestRunner->doRun() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php:176
    PHP   5. PHPUnit_Framework_TestSuite->run() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/TextUI/TestRunner.php:349
    PHP   6. PHPUnit_Framework_TestSuite->run() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:705
    PHP   7. PHPUnit_Framework_TestSuite->runTest() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:745
    PHP   8. PHPUnit_Framework_TestCase->run() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/Framework/TestSuite.php:775
    PHP   9. PHPUnit_Framework_TestResult->run() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:783
    PHP  10. PHPUnit_Framework_TestCase->runBare() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/Framework/TestResult.php:648
    PHP  11. UserTest->setUp() /usr/share/phpunit/vendor/phpunit/phpunit/PHPUnit/Framework/TestCase.php:835
    PHP  12. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/tests/Package/UserTest.php:174
    PHP  13. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/tests/Package/UserTest.php:174
    PHP  14. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  15. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  16. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:0
    PHP  17. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  18. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  19. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:0
    PHP  20. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  21. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  22. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:0
    PHP  23. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  24. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  25. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:0
    PHP  26. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  27. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  28. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:0
    PHP  29. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  30. Illuminate\Foundation\Artisan->add() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82
    PHP  31. Illuminate\Foundation\Artisan->__call() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:0
    PHP  32. call_user_func_array() /dev.app/workbench/antonio/package/vendor/laravel/framework/src/Illuminate/Foundation/Artisan.php:82

正确实例化和使用Artisan的任何线索?

1 个答案:

答案 0 :(得分:0)

模拟连接

模拟数据库连接变得复杂(I've done it before, it's messy!)。

这是几个月前经过大量试验和错误后我在a unit test工作过的一些代码:

Illuminate\Database\Eloquent\Model::setConnectionResolver($resolver = m::mock('Illuminate\Database\ConnectionResolverInterface'));
$resolver->shouldReceive('connection')->andReturn($mockConnection = m::mock('Illuminate\Database\ConnectionInterface'));
$mockConnection->shouldreceive('getPostProcessor')->andReturn(m::mock('Illuminate\Database\Query\Processors\Processor'));
$mockConnection->shouldReceive('getQueryGrammar')->andReturn($queryGrammar = m::mock('Illuminate\Database\Query\Grammars\Grammar'));
$queryGrammar->shouldReceive('getDateFormat')->andReturn('Y-m-d H:i:s');

使用sqllite

然后,我建议实际使用sqlite数据库来测试数据库连接。我发现这更容易了。

使用PHPunit进行测试会触发Laravel中的testing环境,因此您可以在该环境中定义内存(仅针对该请求)sqlite数据库连接,甚至可以在测试设置中播种。

以下是testing using an in-memory sqlite database的示例要点。

测试已经测试过的东西

您的单元测试可能过于简单,例如,我不确定 - 但是,您正在测试already tested in Laravel的内容。仔细考虑您决定测试的内容:D