Include all App loads in UnitTests - unit-testing

I'm attemption a UnitTest like this in FuelPHP:
/**
* Products class tests
*
* #group App
* #group Products
*/
class Test_Model_Products extends Fuel\Core\TestCase
{
public function test_foo() {
$m = new Model_Productpropertytype;
$m->name = 'Text';
$m->save();
}
}
..but there seems to be namespace issues. How can I get the TestCase to not fail on the loaded ORM?
1) Test_Model_Products::test_foo
Fuel\Core\Database_Exception: SQLSTATE[HY000] [2002] No such file or directory

This does not look like an auto loading problem, the error, to me, says that there is a problem with you SQL connection. Fuel uses a separate DB config for the development, testing and production environments.
If you set up a db.php config file in fuel/app/config/testing/db.php it will be used to make any DB connections when running unit tests via oil

Related

Symfony 5 - One entity, one Repository and two Databases

I have a problem querying my database via Symfony Repository.
If I don't specify a repository
/**
* ProductsText
*
* #ORM\Table(name="products_text")
* #ORM\Entity
*/
i can select one of my databases by using Doctrine like this:
->getRepository(ProductsText::class, "db1").
But if i declare the repository:
/**
* ProductsText
*
* #ORM\Table(name="products_text")
* #ORM\Entity(repositoryClass="App\Repository\Product\ProductsTextRepository")
*/
It only selects the database from which I pulled the entity from.
I can't use two different entities because the user selects the "database" when logging in. Unfortunately, I can't merge the two databases yet either, as they are not multi-tenant.
My guess is that I can solve the problem by keeping the registry from the repository in general. My previous attempts unfortunately ended up with the front end no longer loading.
Works, but only for one database:
class ProductsTextRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, ProductsText::class);
}
Did not works:
class TbProductsTextRepository
{
/**
* #var EntityRepository
*/
private $repository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(TbProductsText::class);
}
Unfortunately, I don't understand the mechanics of how the repositorys are regestrated.
I use:
Symfony 5.2
Doctrine 2.2
Doctrine ORM 2.8
Doctrine Migrations Bundle 3.0
I solved the problem by not "registering" the repository.
By using EntityRepository and without a construct, I can use the repository for both databases.
use Doctrine\ORM\EntityRepository;
class TbProductsTextRepository extends EntityRepository
{

Grails Spock unit test requires to mock transaction manager

In Grails 3.1.12, I want to unit test a service:
#Transactional
class PlanService {
List<Plan> getPlans(Map params) {
def currentUser = (User)springSecurityService.getCurrentUser()
return Plan.findAllByCompany(currentUser.employer, params)
}
}
Like this:
#TestFor(PlanService)
#Mock([Plan, User, Company])
class PlanServiceSpec extends Specification {
void "Retrieve plan from the current user"() {
setup:
// create and save entities here
when: "the plans are retrieved"
def params = null
def plans = service.getPlans(params)
then: "the result should only include plans associated to the current user's company"
plans.size() == 2
}
Running the test from the console:
grails> test-app my.PlanServiceSpec -unit
Fails with:
my.FundingPlanServiceSpec > Retrieve plan from the current user FAILED
java.lang.IllegalStateException at PlanServiceSpec.groovy:48
and in the test report (HTML):
java.lang.IllegalStateException: No transactionManager was specified.
Using #Transactional or #Rollback requires a valid configured transaction manager.
If you are running in a unit test ensure the test has been properly configured
and that you run the test suite not an individual test method.
Now if I comment out the #Transactional annotation in the service, the test passes, but that's not the intended implementation. I am able to work around the problem by mocking the transaction manager:
service.transactionManager = Mock(PlatformTransactionManager) {
getTransaction(_) >> Mock(TransactionStatus)
}
But this seems very awkward, if not wrong.
Is there some incantation I forgot to invoke?
EDIT: looks similar to an old bug, but it's been closed more than a year.
Have you tried what a comments says that fixes the problem? If not, try to annotate the test class with:
#TestMixin(DomainClassUnitTestMixin)
and then:
service.transactionManager = getTransactionManager()
Was getting the same error in grails 3.3.2 when trying to test transactional service.
adding DataTest interface solved the issue for me.
class HelloServiceSpec extends Specification implements ServiceUnitTest<HelloService>, DataTest {
}

Unit testing of a class reading a configuration file

I have a class "Configuration" that has a method "getConfig" that reads a configuration file "config.ini" where I have all the app configs (database credentials and host, some apis keys, .....)
For now I have this unit test that tests if the database entry exists in the config file and at the same time confirms that the array returned by the method "getConfig" has the key "database":
function testConfigFileHasDatabaseEntry()
{
$configuration = Configuration::getInstance();
$arrConfig = $configuration->getConfig();
$this->assertArrayHasKey('database', $arrConfig);
}
I have also another unit test that confirms that "getConfig" returns a variable of type array.
My question is the following:
In terms of unit testing best practices, in this case is this test enough to confirm that the function getConfig is well tested or it is better to confirm that every key exists in the config file. I think confirming that all entries are in the config file maybe falls under another category of testing, but I want to be sure.
Let me know what is the best practice in this case.
Base on the answer of gcontrollez I realized it is better to post the class source code:
<?php
/**
* Loads the configuration file
*/
namespace Example\Lib;
class Configuration {
private static $instance;
private $arrConfig;
/**
* Constructor: loads the config file into property arrConfig and dies if unable
* to load config file
*
* #return void
*/
private function __construct()
{
$this->arrConfig = parse_ini_file("config/settings.ini", true);
if ($this->arrConfig == false){
die("Cannot load configuration file");
}
}
/**
* returns an instance of this singleton class
*
* #return Configuration
*/
public static function getInstance()
{
if (self::$instance == null){
self::$instance = new Configuration();
}
return self::$instance;
}
/**
* Getter for the property arrConfig
*
* #return array:
*/
public function getConfig() {
return $this->arrConfig;
}
}
Thanks
You are not unit testing the getConfig method. You are just checking that its result contains certain data. This is perfectly valid and can be useful but is not a unit test.
If you wanted to unit test the getConfig method, you should check it's behaviour with each possible config.ini file. I suppose you are using the parse_ini_file function inside getConfig. So in order to unit test the getConfig method you should check all the possible cases you think that can happen:
- testConfigFileIsLoaded
- testExceptionThrownIfConfigFileFailsToLoad
The parse_ini_file returns an array or false so those are the cases that you should check.
For that you need to be able to change the .ini file to be used. If it's harcoded inside the Configuration class you wont be able to do that.

Grails build-test-data Plugin - Can't Find TestDataConfig.groovy

I'm trying to utilize the build-test-data plugin in my Grails (v2.4.3) app to assist with test data creation for unit testing, but while running my unit tests the plugin cannot find TestDataConfig.groovy to load my specified values (for unique constraint tests, etc).
I've installed the plugin via including it in BuildConfig.groovy:
plugins {
...
test ":build-test-data:2.2.0"
...
}
I've ran the following command to create the TestDataConfig.groovy template, which places the file at \grails-app\conf\:
grails install-build-test-data-config-template
I've followed the general instructions on the plugin wiki to come up with a properly formatted file:
testDataConfig {
sampleData {
'<path>.User' {
def a = 1
username = { -> "username${a++}" }
}
}
}
(Where path is the fully-qualified class name.)
In my tests, I am using the following general format:
import grails.buildtestdata.TestDataConfigurationHolder
import grails.buildtestdata.mixin.Build
import grails.test.mixin.TestFor
import spock.lang.Specification
import spock.lang.Unroll
#TestFor(User)
#Build(User)
class UserSpec extends Specification {
def setup() {
mockForConstraintsTests(User)
TestDataConfigurationHolder.reset()
user = User.buildWithoutSave()
}
#Unroll
void "test #field must be unique"() {
given: 'a User exists'
user.save(flush: true)
when: 'another User is created with a non-unique field value'
def nonUniqueUser = User.buildWithoutSave()
nonUniqueUser."$field" = user."$field"
then: 'validation fails and the field has a unique constraint error'
!nonUniqueUser.validate()
nonUniqueUser.errors.errorCount == 1
nonUniqueUser.errors.getFieldError("$field").code == 'unique'
where:
field << ['username', '<some other field>']
}
}
But, when the test is run (using IntelliJ IDEA) TestDataConfig.groovy cannot be found via the following method in the plugin:
static Class getDefaultTestDataConfigClass() {
GroovyClassLoader classLoader = new GroovyClassLoader(TestDataConfigurationHolder.classLoader)
String testDataConfig = Holders.config?.grails?.buildtestdata?.testDataConfig ?: 'TestDataConfig'
try {
return classLoader.loadClass(testDataConfig)
} catch (ClassNotFoundException ignored) {
log.warn "${testDataConfig}.groovy not found, build-test-data plugin proceeding without config file"
return null
}
}
So the test continues on without a config file and I do not get uniquely generated data sets.
I've even tried explicitly including the file in Config.groovy:
grails.buildtestdata.testDataConfig = "TestDataConfig"
But, the same method in the plugin shows that Holders.config? is null.
I've looked at a few solutions to a similar problem here on StackOverflow with nothing working in my case; I cannot figure out how to get my app to detect the presence of the TestDataConfig.groovy file.
Any ideas? Thanks so much!

How to enable Doctrine query logging in Symfony 1.4 unit tests

I am unit testing a model class and I would like all Doctrine queries to be logged.
My settings.yml for the test environment contains
logging_enabled: true
and my script
$configuration = ProjectConfiguration::getApplicationConfiguration( 'frontend', 'test', true);
new sfDatabaseManager( $configuration ) ;
Still, I don't see any log in any log file.
So, I found a workaround by using an event listener on the Doctrine profiler.
$profiler = new Doctrine_Connection_Profiler();
$conn = Doctrine_Manager::connection();
$conn->setListener($profiler);
/* tests go here */
foreach ($profiler as $event) {
echo $event->getQuery() . "\n";
}
But the same query is printed out several times for some reason (I am sure it is executed only once). Plus it is not so convenient to have the query logs dissociated from the rest of the log messages.