When using AbstractControllerTestCase (or it's subclasses) you get a convenient method setApplicationConfig() that let's you pass an array similar to config/application.config.php, so that you include only the modules you need in order to test.
How do you pass the array that goes into config/autoload/global.php to AbstractControllerTestCase?
PS: if it helps, I'm trying to pass a custom ORM connection that uses SQLite
You can simply make separate config files to be used when testing and load those inside your test controller.
for example;
copy config/application.config.php to config/application.config.test.php
Make a small change to allow us to load separate test config files without touching the global config files used by the production application.
'config_glob_paths' => array(realpath(__DIR__) . '/autoload/{,*.}{global,test}.php'),
This will allow us to override any config values we need as the test config files are loaded after the usual global config files. We can now please any test specific configureation inside test.php, anything.test.php etc.
now you can copy
autoload/global.php to autoload/test.php
You can now change config items and these will override those inside global.php
autoload/test.php
<?php
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'sqlite:' . __DIR__ .'/../../data/testing.sqlite',
//'dsn' => 'mysql:dbname=somedatabase;host=localhost',
'username' => 'dbuser',
'password' => 'passwordgoeshere',
),
You could also change the driver to use SQL lite or what ever your require to run your tests.
Now you just need to make your test controllers load our new application config file:
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
class ExampleTest extends AbstractHttpControllerTestCase
{
public function setUp()
{
$this->setApplicationConfig(
include __DIR__ . '/../../config/application.config.test.php'
);
}
This allows you to keep all your test configuration separate to your main application config settings.
Related
I've created a simple application in ZF2. At some point I decided to create a new set of functionalities so I created a new folder this way:
module
Application
src
Application
Controller
IndexController.php
Issue
Controller
FooController.php
IndexController has the namespace Application\Controller and actions are working fine but when I try to run action from FooController (namespace Issue\Controller) it throws Class 'Issue\Controller\FooController'. Of course I've set routes and controllers in configuration (without it it was throwing 404 anyway).
The problem lies in the fact that your folder name in src should correspond to the folder name of the module. I think this is related to the autoloading namespace magic in ZF2.
So like #Demo suggests you need to do this:
module
Application
src
Application
Controller
IndexController.php
Issue
src
Issue
Controller
FooController.php
or this:
module
Application
src
Application
Controller
IndexController.php
FooController.php
Read more on the topic here at this question on StackOverflow
EDIT
Read also more on correctly setting up your module, properly autoloading through autoLoaderConfig in your module.php and PSR-0 naming conventions here in the ZF2 user-guid
It is indeed an autoload problem (but no magic).
You can register your namespace like this (just an quick example) :
<?php
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
'Application' => __DIR__ . '/src/Application',
'Issue' => __DIR__ . '/src/Issue',
),
),
);
}
}
EDIT
For PSR-0 compliance, you could put a Module.php file in Application and Issue folders, and the "global" Module.php would look like this :
<?php
require_once __DIR__ .'/src/Application/Module.php';
require_once __DIR__ .'/src/Issue/Module.php';
And you could also register your autoloading namespaces in each Module.php file.
And again, you should prefer using two modules.
I want to make sure this works the way I think it does.
I have setup DB info inside of myapp/config/autoload/global.php like this:
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2tutorial;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
...
Now I'm messing around with a new module and would like to configure that specific module with a different db. If I add a 'db' config array to NewModule/config/module.config.php will it overwrite the global config? I'm not sure if the application wide global.php file is the same as a module specific config file or if it has a special specification- like accepting a db configuration while module specific config files do not.
edit: Well I tried this and it appears the db entry I added in module.config is being completely ignored. How can I override the db config per module? It would be very convenient for testing purposes.
If I add a 'db' config array to NewModule/config/module.config.php will it overwrite the global config?
Yes. All configs are merged together in to one monster array.
ZF support multiple adapters, you'll just have to refer to them by name in code so it knows which one you want. See this blog post for details on how to set it up: http://samsonasik.wordpress.com/2013/07/27/zend-framework-2-multiple-named-db-adapter-instances-using-adapters-subkey/
Is there a way of setting the database name dynamically (coming originally from database.yml), ideally using part of the application pathname?
Background of the question is, I have a single source code that shall run on one and the same server multiple times but each instance of the application should have a different database.
Example, I have an auction site which works with the currency USD. Now I want to run the same auction site again (one the same server) for a second currency. For valid reasons I don't want to make the application multi-currency capable, I'ld like to keep the source code as is.
Setting up the application on the same server using sub-URL I will follow this approach:
http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rack_to_sub_uri
The question left is, how does each instance of the application get its own DB name, e.g. the one instance uses the database name production_USD and the otherone uses production_CAD
Edit: The solution works like a charm, thanks to the feedback received:
My folder structure on the server is
/var/www/auction/USD-US Dollar
/var/www/auction/CAD-Canadian Dollar
/var/www/auction/source
/var/www/logs
With the source folder containing the original source code and the USD and CAD being links to the source (no actual need for copying any code anywhere other than placing it into source.
Next to set the DB dynamically. The currency is determined automatically by looking
at the folder name. I put it into the application.rb as I need it to
in an early stage because I also want different log files for the different currencies.
I am storing the log files outside of the source folder to make sure I don't loose them
when the source folder gets refreshed from the QA system
Here the code changes:
application.rb:
fname = File.basename(File.expand_path('../../', __FILE__))
curr = fname.split("-")
if curr[1].nil?
CURR_SHORT = "XXX"
CURR_LONG = "XXX"
else
CURR_SHORT = curr[0]
CURR_LONG = curr[1]
end
dbname = "myapp_#{CURR_SHORT}_#{Rails.env[0..2]}"
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => dbname
)
module Virex
class Application < Rails::Application
config.logger = ActiveSupport::BufferedLogger.new("../logs/#{Rails.env}.#{CURR_SHORT}.log")
....
Of course, have a look at ActiveRecord::Base.establish_connection :
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
You can put this piece of code in an initializer, with the database name you want, depending on your pathname.
Complete doc here
It seem that all config settings defined in Module.php in getConfig method are merged globally across the application. It's pretty weird for my case, because I need different configs for each module: database settings, some factories and view_manager settings which are currently overridden by the last module loaded. How can I use configs exclusive for some module is scope of $this->getServiceLocator()->get('Config') in that module. The only thoughts I have now are to merge my module config with $this->getServiceLocator()->get('Config') on dispatch event, if that is the only case, what priority is better to use so I can utilize all settings: view_manager, service_manager ect?
For me the ideal solution will be if configs settings in scope of some namespace will be used only under that namespace.
You can nest your configuration values as deeply as you like.
Imaging you've got a module called "mymodule", and it needs to connect to a special, module-specific database (distinct from the main DB for the overall application). You would do something like this:
mymodule.global.php.dist:
return array(
'mymodule' => array(
'db' => array('host'=>'localhost', ... )
)
)
Then just make sure that myModule is looking at $config['mymodule']['db'], and not $config['db']
You can get the configuration settings of the module in this way:
$moduleManager = $this->getServiceLocator()->get('ModuleManager');
$applicationModule = $moduleManager->getModule('Application');
$applicationConfig = $applicationModule->getConfig();
Using Zend Framework version 2, how to configure different databases for different modules. Each module will have access to different database.
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=test;host=localhost',
'driver_options' => array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''),
'username' => 'root',
'password' => '',
),
placed above code in module.config.php for each module with different DB name
Thanks in advance
The concept of a module configuration is actually more that the module is providing some configuration for the application. The supplied configuration is merged into a single configuration and therefore using the same configuration key names will cause this data to be overwritten.
So instead use descriptive names - db_user or db_logging etc.
Also it's probably a good idea to look at ServiceManager factories, as you can pull out some common database credentials and then use a different database name depending on which factory is being used.
I've only lightly touched on databases in ZF2 so maybe someone else will offer a better approach.