title,body,link,tags,view_count,is_answered,score,answer_count
DataBase Testing By using Autowire in Integration Testing,"<p>I am new to DataBase testing and I am trying to Connect the database by using tag @SpringBootTest in class level and by using Autowire, It is not creating instantiation getting always null</p>

<pre class=""lang-java prettyprint-override""><code>@SprintBootTest
 Class  Test{
@Autowire
     DatabaseService databaseService;

}

</code></pre>

<p>Can anyone suggest please? If any one did similar like this , can you please give me the instructions </p>
",https://stackoverflow.com/questions/59572795/database-testing-by-using-autowire-in-integration-testing,"['java', 'spring-boot', 'cucumber', 'integration-testing', 'autowired']",140,True,2,1
Android database testing - using Room.inMemoryDatabaseBuilder() passes exact same test that Room.databaseBuilder() does not,"<p>I am writing units tests for an app's Room database. Here is relevant code when using <code>Room.databaseBuilder()</code></p>

<pre><code>@Before
public void createDb() {
    Context context = ApplicationProvider.getApplicationContext();
    db = Room.databaseBuilder(context, AppDatabase.class, ""AppDatabase"").build();
    itemDao = db.itemDao();
}
</code></pre>

<p>The test fails here and the error is <code>android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: item.id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY[1555])</code>. (I think I know what causes the error, I need I don't have an auto generated primary key for entries so a record is inserted with an id already in the table. Anyway, that's not what my question is.)</p>

<p>And same method, using <code>Room.inMemoryDatabaseBuilder()</code>. Here the test passes.</p>

<pre><code>@Before
void createDb() {
    Context context = ApplicationProvider.getApplicationContext();
    db = Room.inMemoryDatabaseBuilder(context, AppDatabase.class).build();
    itemDao = db.itemDao();
}
</code></pre>

<p>And the test itself is:</p>

<pre><code>@Test
public void writeItemAndReadInList() {
    float value = 3.0f;
    Item item = new Item(value, new Date());
    itemDao.insert(item);
    List&lt;Item&gt; all = itemDao.getAll();
    assertEquals(all.get(0).getValue(), value);
}
</code></pre>

<p>So the question is why does the first method fail and the second one pass? What difference is that one database is created in memory and the other not? If the problem is with inserting with unique primary keys, shouldn't it be present in both methods? Unless that is not the problem here.</p>
",https://stackoverflow.com/questions/61332685/android-database-testing-using-room-inmemorydatabasebuilder-passes-exact-sam,"['android', 'database', 'unit-testing', 'testing', 'junit']",781,True,0,1
How to perform unit testing with databases in PHP Unit 8.0 or greater,"<p>I am running a PHP project and I am using PHPUnit for unit testing. Up until recently I used PHPUnit 4.0 with DBUnit as an extension for database testing. I changed now to PHPUnit 8.0 but could not find a suitable database testing extension to test my backend functions with a test database connected. Also the documentation of PHPUnit does not contain any hint for database testing.</p>

<p>What module/extension replaces DBUnit for PHPUnit 8.0 or higher?</p>

<p>Thanks</p>

<p>Christian</p>
",https://stackoverflow.com/questions/61975330/how-to-perform-unit-testing-with-databases-in-php-unit-8-0-or-greater,"['database', 'phpunit', 'dbunit']",195,False,1,0
Testing Laravel lighthouse mutations with database,"<p>I am trying to use database and laravel-lighthouse in tests. I am using the traits for GraphQL and Database Testing, mutation works but tests don't.</p>

<pre class=""lang-php prettyprint-override""><code>class MyTest extends TestCase{
  use MakesGraphQLRequests;
  use RefreshDatabase;
  public function testGraphQLDatabaseTest(){
    $this-&gt;graphQL(/** @lang GraphQL */ '
        mutation CreatePost($title: String!) {
            createPost(title: $title) {
                id
            }
        }
    ',['title' =&gt; 'test title']);

    $this-&gt;assertDatabaseHas('posts', [
        'title' =&gt; 'test title',
    ]); // It says that expect table posts with title' =&gt; 'test title' but 'posts' table is empty
  }
}
</code></pre>
",https://stackoverflow.com/questions/62216848/testing-laravel-lighthouse-mutations-with-database,"['laravel', 'phpunit', 'laravel-lighthouse', 'laravel-testing']",425,True,0,2
DataBase Testing By using Autowire in Integration Testing,"<p>I am new to DataBase testing and I am trying to Connect the database by using tag @SpringBootTest in class level and by using Autowire, It is not creating instantiation getting always null</p>

<pre class=""lang-java prettyprint-override""><code>@SprintBootTest
 Class  Test{
@Autowire
     DatabaseService databaseService;

}

</code></pre>

<p>Can anyone suggest please? If any one did similar like this , can you please give me the instructions </p>
",https://stackoverflow.com/questions/59572795/database-testing-by-using-autowire-in-integration-testing,"['java', 'spring-boot', 'cucumber', 'integration-testing', 'autowired']",140,True,2,1
@DataJpaTest updating actual data in case of MySQL but working fine with H2,"<p>I am learning @DataJpaTest, my test case is as below</p>

<pre><code>import com.demo.mockito.entity.StudentEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class StudentRepositoryTest {
    @Autowired
    private StudentRepository studentRepository;
    @Test
    public void findAll() {
        StudentEntity student1 = new StudentEntity(""shrikant"", new Date());
        studentRepository.save(student1);
        List&lt;StudentEntity&gt; entityList = studentRepository.findAll();
        assertEquals(1, entityList.size());
    }
}
</code></pre>

<p>it's giving me the error </p>

<pre><code>expected: &lt;1&gt; but was: &lt;33&gt;
Expected :1
Actual   :33
&lt;Click to see difference&gt;
</code></pre>

<p>because right now there are 33 records in DB, and with every save test case, it increases.</p>

<p>src/main/test/application.properties</p>

<pre><code>spring.datasource.url=jdbc:mysql://localhost:3306/student_db?jdbcCompliantTruncation=false&amp;sessionVariables=sql_mode='NO_ENGINE_SUBSTITUTION'&amp;useSSL=false&amp;useServerPrepStmts=false&amp;rewriteBatchedStatements=true&amp;useUnicode=true&amp;characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.jpa.database.schema=student_db
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
</code></pre>

<p>build.gradle</p>

<pre><code>plugins {
    id 'java'
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}
group 'com.demo.mockito'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.0')
    runtime 'mysql:mysql-connector-java'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
test {
    useJUnitPlatform()
}
</code></pre>

<p>if i use h2 instead, it gives correct result beucase every time it recreates a new instance with no data.</p>

<p>is this intended behavior? or am I doing something wrong, 
is h2 standard in case of database testing.
but I don't want to configure another database in my application when my intention is to test MySQL only.</p>
",https://stackoverflow.com/questions/61557012/datajpatest-updating-actual-data-in-case-of-mysql-but-working-fine-with-h2,"['spring-boot', 'jpa', 'testing', 'spring-data-jpa', 'integration-testing']",1237,True,1,1
Trying to compare Home Object to String Object in unit testing,"<p>I'm trying to test whether a method works or not in my unit testing. As seen in the code below in my error, I'm trying to compare my Home Object to my String Object and when printing out both of them, they are certainly equal to each other. My question is how do I change my Home Object to be a String Object or my String Object to be a Home Object so the test passes. Also if it helps this is in-memory database testing too. Thanks!</p>

<p><strong>Unit testing code</strong></p>

<pre><code>from unittest import TestCase
from main import ContactApp
from database import CombinedDatabase, Home, Person, Location, Contact

     class TestContactApp(TestCase):
         def test_commit_data(self):
         url = CombinedDatabase.construct_in_memory_url()
         contact_database = CombinedDatabase(url)
         contact_database.ensure_tables_exist()
         session = contact_database.create_session()
         home_address = Home(address='3069 U St.')
         patient1 = Person(patient_name='Mike Piazza')
         ContactApp.commit_data(session, str(patient1), str(home_address), '456324A', 96.4, 'USA',  'Nebraska', 'Omaha', '54229')
         actual = session.query(Home).one()
         actual2 = session.query(Person).one()
         print(home_address, actual.address)
         self.assertEqual(home_address, actual.address)
         self.assertEqual(patient1, actual2.patient_name)
</code></pre>

<p><strong>Error</strong></p>

<pre><code>&lt;database.Home object at 0x7fe4ae20ce48&gt; &lt;database.Home object at 0x7fe4ae20ce48&gt;
#printed out objects

&lt;database.Home object at 0x7fe4ae20ce48&gt; != &lt;database.Home object at 0x7fe4ae20ce48&gt;

&lt;database.Home object at 0x7fe4ae20ce48&gt;
&lt;database.Home object at 0x7fe4ae20ce48&gt;
&lt;Click to see difference&gt;

Traceback (most recent call last):
  File ""/home/cse/Pycharmedu2019.1.1/pycharm-edu-2019.1.1/helpers/pycharm/teamcity/diff_tools.py"", line 32, in _patched_equals
old(self, first, second, msg)
  File ""/usr/lib64/python3.6/unittest/case.py"", line 829, in assertEqual
assertion_func(first, second, msg=msg)
  File ""/usr/lib64/python3.6/unittest/case.py"", line 822, in _baseAssertEqual
raise self.failureException(msg)
AssertionError: &lt;database.Home object at 0x7fe4ae20ce48&gt; != '&lt;database.Home object at 0x7fe4ae20ce48&gt;'
</code></pre>
",https://stackoverflow.com/questions/61451152/trying-to-compare-home-object-to-string-object-in-unit-testing,"['python', 'unit-testing', 'in-memory-database']",141,True,0,1
Use Flyway migration on Integration Tests using H2,"<p>I'm trying to create a in-memory database with flyway migration to perform my Spring Boot Integration tests.</p>
<p>But when I execute the test suite, with a single and simple test, I'm getting this error:</p>
<pre><code>  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.5.RELEASE)

2020-11-10 21:30:48.381  INFO 3252 --- [           main] b.c.f.babysitter.AcaoIntegrationTests    : Starting AcaoIntegrationTests on DESKTOP-KG8MEOV with PID 3252 (started by vinic in C:\Users\vinic\Documents\Spring\workspace_fiap\babysitter)
2020-11-10 21:30:48.382  INFO 3252 --- [           main] b.c.f.babysitter.AcaoIntegrationTests    : No active profile set, falling back to default profiles: default
2020-11-10 21:30:48.619  INFO 3252 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFERRED mode.
2020-11-10 21:30:48.659  INFO 3252 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 39ms. Found 2 JPA repository interfaces.
2020-11-10 21:30:48.949  INFO 3252 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 0 (http)
2020-11-10 21:30:48.950  INFO 3252 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-11-10 21:30:48.950  INFO 3252 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.39]
2020-11-10 21:30:48.951  INFO 3252 --- [           main] o.a.catalina.core.AprLifecycleListener   : Loaded Apache Tomcat Native library [1.2.25] using APR version [1.7.0].
2020-11-10 21:30:48.951  INFO 3252 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
2020-11-10 21:30:48.951  INFO 3252 --- [           main] o.a.catalina.core.AprLifecycleListener   : APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
2020-11-10 21:30:48.952  INFO 3252 --- [           main] o.a.catalina.core.AprLifecycleListener   : OpenSSL successfully initialized [OpenSSL 1.1.1g  21 Apr 2020]
2020-11-10 21:30:48.989  INFO 3252 --- [           main] o.a.c.c.C.[Tomcat-1].[localhost].[/]     : Initializing Spring embedded WebApplicationContext
2020-11-10 21:30:48.989  INFO 3252 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 603 ms
2020-11-10 21:30:49.036  INFO 3252 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Starting...
2020-11-10 21:30:49.038  INFO 3252 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Start completed.
2020-11-10 21:30:49.038  INFO 3252 --- [           main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
2020-11-10 21:30:49.174  INFO 3252 --- [           main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:h2:mem:testdb (H2 1.4)
2020-11-10 21:30:49.182  INFO 3252 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.005s)
2020-11-10 21:30:49.190  INFO 3252 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table &quot;PUBLIC&quot;.&quot;flyway_schema_history&quot; ...
2020-11-10 21:31:19.205  WARN 3252 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.exception.FlywaySqlException: 
Unable to obtain connection from database: HikariPool-2 - Connection is not available, request timed out after 30003ms.
-----------------------------------------------------------------------------------------------------------------------
SQL State  : null
Error Code : 0
Message    : HikariPool-2 - Connection is not available, request timed out after 30003ms.

2020-11-10 21:31:19.205  INFO 3252 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Shutdown initiated...
2020-11-10 21:31:19.206  INFO 3252 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Shutdown completed.
2020-11-10 21:31:19.206  INFO 3252 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2020-11-10 21:31:19.213  INFO 3252 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-11-10 21:31:19.214 ERROR 3252 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.exception.FlywaySqlException: 
Unable to obtain connection from database: HikariPool-2 - Connection is not available, request timed out after 30003ms.
-----------------------------------------------------------------------------------------------------------------------
SQL State  : null
Error Code : 0
Message    : HikariPool-2 - Connection is not available, request timed out after 30003ms.

    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:311) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109) ~[spring-context-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405) ~[spring-boot-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120) ~[spring-boot-test-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) ~[spring-test-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) ~[spring-test-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123) ~[spring-test-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.outputConditionEvaluationReport(SpringBootDependencyInjectionTestExecutionListener.java:53) ~[spring-boot-test-autoconfigure-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:46) ~[spring-boot-test-autoconfigure-2.3.5.RELEASE.jar:2.3.5.RELEASE]
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244) ~[spring-test-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98) ~[spring-test-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:341) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:346) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:341) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177) ~[na:na]
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312) ~[na:na]
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) ~[na:na]
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658) ~[na:na]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:340) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:263) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:256) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at java.base/java.util.Optional.orElseGet(Optional.java:362) ~[na:na]
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:255) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:29) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:108) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:107) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:71) ~[junit-jupiter-engine-5.6.3.jar:5.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) ~[junit-platform-engine-1.6.3.jar:1.6.3]
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248) ~[.cp/:na]
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211) ~[.cp/:na]
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226) ~[.cp/:na]
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199) ~[.cp/:na]
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:141) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464) ~[.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210) ~[.cp/:na]
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: 
Unable to obtain connection from database: HikariPool-2 - Connection is not available, request timed out after 30003ms.
</code></pre>
<p>Basically, flyway is throwing an error after trying to connect to the H2 database, and, apparently, the database is currently off.</p>
<p>I can access the console on <code>localhost:8080/h2-console</code>, but cannot log-in, with the error message:</p>
<p><code>Database &quot;mem:testdb&quot; not found, either pre-create it or allow remote database creation (not recommended in secure environments) [90149-200] 90149/90149 (Help)</code></p>
<p>My application-test.properties (which I'm using on my test suite):</p>
<pre><code>spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=stars
spring.datasource.password=C0nst3llat10n

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

spring.flyway.locations=classpath:db/tests

spring.datasource.hikari.maximum-pool-size=1
</code></pre>
<p>How can I avoid this to use H2 only as database testing case?</p>
",https://stackoverflow.com/questions/64778849/use-flyway-migration-on-integration-tests-using-h2,"['spring-boot', 'h2', 'flyway']",888,True,0,1
Laravel 8 Multiple Relationships for Factory,"<p>In Laravel 8 it is possible to quickly fill relationships with factories. However, I cannot figure out how to generate more than one relationship. <strong>How can I create a random or new relationship for each link using the new Laravel 8 syntax?</strong></p>
<p>This factory syntax is only available in Laravel 8.
<a href=""https://laravel.com/docs/8.x/database-testing#factory-relationships"" rel=""noreferrer"">https://laravel.com/docs/8.x/database-testing#factory-relationships</a></p>
<h2>Problem</h2>
<p>Consider the following relationship:</p>
<ul>
<li>Each link belongs to a website and a post.</li>
<li>Both websites and posts can have many links.</li>
</ul>
<pre><code>&lt;?php

class Post extends Model
{
    use HasFactory;

    function links()
    {
        return $this-&gt;hasMany(Link::class);
    }
}

class Website extends Model
{
    use HasFactory;

    function links()
    {
        return $this-&gt;hasMany(Link::class);
    }
}

class Link extends Model
{
    use HasFactory;

    function post()
    {
        return $this-&gt;belongsTo(Post::class);
    }

    function website()
    {
        return $this-&gt;belongsTo(Website::class);
    }
}

</code></pre>
<hr />
<h2>What I tried/want</h2>
<p>What I tried below will only generate one model for all the links. <strong>How can I create a random or new relationship for each link using the new Laravel 8 syntax?</strong></p>
<pre><code>Link::factory()-&gt;count(3)-&gt;forPost()-&gt;forWebsite()-&gt;make()

=&gt; Illuminate\Database\Eloquent\Collection {#4354
     all: [
       App\Models\Link {#4366
         post_id: 1,
         website_id: 1,
       },
       App\Models\Link {#4395
         post_id: 1, // return a different ID
         website_id: 1,
       },
       App\Models\Link {#4370
         post_id: 1, // return a different ID
         website_id: 1, // return a different ID
       },
     ],
   }
</code></pre>
",https://stackoverflow.com/questions/63821850/laravel-8-multiple-relationships-for-factory,"['php', 'laravel', 'laravel-factory']",16991,True,5,6
Having problem with changing Hibernate configuration at runtime,"<p>I have developed a Java standalone application for Hibernate &amp; H2 database testing purposes. This application works simply; First, it configures a database connection on the current machine disk space (Using the H2 URL-Only feature), then it closes the current session factory and tries to initialize a new configuration to a new H2 database. Everything is good, but after switching to the new database when a query is sent to the Hibernate this error will be shown:</p>

<p><code>java.lang.IllegalStateException: EntityManagerFactory is closed</code></p>

<p>Here is the Hibernate configuration class:</p>

<pre><code>public class ProjectHibernateConfiguration {
    private SessionFactory sessionFactory;
    private static ProjectHibernateConfiguration instance;

    private ProjectHibernateConfiguration(String url) {
        try {
            Configuration configuration = new Configuration();

            Properties settings = new Properties();
            settings.put(Environment.DRIVER, ""org.h2.Driver"");
            settings.put(Environment.URL, ""jdbc:h2:"" + url);
            settings.put(Environment.USER, ""user"");
            settings.put(Environment.PASS, ""pass"");
            settings.put(Environment.SHOW_SQL, ""true"");
            settings.put(Environment.DIALECT, ""org.hibernate.dialect.H2Dialect"");
            settings.put(Environment.HBM2DDL_AUTO, ""update"");
            settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, ""thread"");
            settings.put(Environment.C3P0_MIN_SIZE, ""5"");
            settings.put(Environment.C3P0_MAX_SIZE, ""20"");
            settings.put(Environment.C3P0_TIMEOUT, ""1800"");


            configuration.setProperties(settings);

            ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties())
                                                                           .build();
            sessionFactory = configuration.buildSessionFactory(registry);
        } catch (Exception ignored) {
        }
    }

    public static void initializeConfiguration(String url) {
        instance = new ProjectHibernateConfiguration(url);
    }

    public static ProjectHibernateConfiguration getInstance() {
        return instance;
    }

    public Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    public Session openSession() {
        return sessionFactory.openSession();
    }

    public void closeSessionFactory() {
        this.sessionFactory.close();
    }
</code></pre>

<p>And the Main class:</p>

<pre><code>public class Main {
    public static void main(String[] args) {
        ProjectHibernateConfiguration.initializeConfiguration(""path to a H2 database"");
        //Performing some queries to database (no problems)
        ProjectHibernateConfiguration.getInstance().closeSessionFactory();

        ProjectHibernateConfiguration.initializeConfiguration(""path to a new H2 database"");
        //Performing queries to new initialized database (getting error: java.lang.IllegalStateException: EntityManagerFactory is closed)
    }
}
</code></pre>

<p>After closing the previous session factory the code does create a new session factory but it seems that something is wrong with creating a new session factory.
So what is wrong with this code?</p>
",https://stackoverflow.com/questions/62126692/having-problem-with-changing-hibernate-configuration-at-runtime,"['java', 'hibernate', 'h2']",103,False,0,0
HttpClient PostAsync() doesn&#39;t work while POSTMAN works fine,"<p>I'm trying to post an item on my Azure database account. I wrote and published to the Azure account an ASP.Net Core web application, which implements such methods as Get, Post, Put, and Delete. On my Xamarin Forms project, I'm trying to call HttpClient PostAsync method to create(post) a record in the Azure database. Testing the same transaction on POSTMAN works just fine, but it doesn't work in my Xamarin Forms mobile app. The GetStringAsync method works just fine both on POSTMAN and on my mobile app. I have no idea why the PostAync only doesn't work. Please help!</p>
<p>Here's the event handler method where PostAsync is called:</p>
<pre><code>async void OnAdd(object sender, EventArgs e)
{
    // This item is to be posted to the Azure database.
    var tblmoney_item = new TblMoney
    {
        RecordDate = Convert.ToDateTime(&quot;7-26-2020&quot;),
        ItemDesc = &quot;coffee&quot;,
        AmountOut = 4500,    // The currency unit is in KRW. (KRW 4,500 = US$4).
        SpentTypeId = 3
    };

    // Serialize the item in JSON format.
    var content = JsonConvert.SerializeObject(tblmoney_item);

    // POST the item to the URL. Works fine on POSTMAN, but does NOT work on my mobile app.
    await _client.PostAsync(Url, new StringContent(content));
    
    // Refresh the list view.
    _tblmoney_items.Insert(0, tblmoney_item);
}
</code></pre>
<p>Here's the declaration within the MainPage class of the variables(properties) above:</p>
<pre><code>private const string Url = &quot;https://testwebapi.azurewebsites.net/tblmoney&quot;;
private HttpClient _client = new HttpClient();
private ObservableCollection&lt;TblMoney&gt; _tblmoney_items;
</code></pre>
<p>The item's Class desclaration is as the following:</p>
<pre><code>public partial class TblMoney
{
    public int Id { get; set; }
    public DateTime? RecordDate { get; set; }
    public string ItemDesc { get; set; }
    public int? AmountOut { get; set; }
    public int? SpentTypeId { get; set; }

    public virtual TblSpentType SpentType { get; set; }
}
</code></pre>
<p>Here's the Controller Class in the REST Web API project, which is an ASP.Net Core Web Application project.</p>
<pre><code>[ApiController]
[Route(&quot;[controller]&quot;)]
[Produces(&quot;application/json&quot;)]

public class TblMoneyController : ControllerBase
{
    private mynotedbContext _context = new mynotedbContext();

    [HttpGet]
    public IEnumerable&lt;TblMoney&gt; Get()
    {
        // get all tblMoney items.
        return _context.TblMoney.ToList();
    }

    [HttpPost]
    public IActionResult Post([FromBody]TblMoney tblmoney_item)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _context.TblMoney.Add(tblmoney_item);
        _context.SaveChanges(true);
        return StatusCode(StatusCodes.Status201Created);
    }
}
</code></pre>
<p>The DB context looks like this:</p>
<pre><code>public partial class mynotedbContext : DbContext
{
    public mynotedbContext()
    {
    }

    public mynotedbContext(DbContextOptions&lt;mynotedbContext&gt; options)
        : base(options)
    {
    }

    public virtual DbSet&lt;TblMoney&gt; TblMoney { get; set; }
...
</code></pre>
",https://stackoverflow.com/questions/63096177/httpclient-postasync-doesnt-work-while-postman-works-fine,"['c#', 'asp.net-core', 'asp.net-web-api', 'xamarin.forms', 'postman']",1389,True,4,1
Best practices of phpunit in a complex scenario,"<p>I'm trying to test my php cms and I question many things about why &amp; how:</p>
<ul>
<li>official policy is <strong>NOT</strong> to test protected/private methods</li>
</ul>
<p>but then it's about functional/behavioral testing and not unit testing</p>
<ul>
<li>development of phpunit stopped support of database testing a whole time ago; sth they called it <code>dbunit</code> if I remember right</li>
</ul>
<p>as a result we do have to create complex test classes for database management or because these classes already exist in an extensive work like mine we do have to use methods from other classes existed here and there that facilitate database management so the system under test actually helps the testing software in a close interaction one with the other</p>
<ul>
<li>it is said that testing is actually call your code before even having written it using your awesome command line and move step-by-step to your goal</li>
</ul>
<p>but if your testing <s>code</s> targets a more functional approach then I can call my in-development method with any other way even from command line and debug it sending output to php log with <code>error_log</code>.</p>
<p>Having said that I save all the trouble of writing 100 lines of code + more than 100 lines of test files, changing 100 lines of code + changing more than 100 lines of test files and on and on....</p>
<p>In the above if we add all the arguments about not to test protected/private members we end in a simple question: why that fuss on unit testing of private/protected methods that might have long chain of internal calls when there are much simpler methods of testing while we code?</p>
<p>All the above introduction seems to me necessary for the reader to understand what I'm asking about:</p>
<p><strong>Given the next specific method can you propose the best approach of (unit?) testing?</strong></p>
<h1>1 Method under test</h1>
<p>File is <code>/home/test/server/auth/Auth.php</code></p>
<pre><code>namespace g3\auth;

use g3\Singleton;
use g3\TokenFactory;
use g3\Registry;
use g3\Header;
use g3\Session;
use g3\Lang;
use g3\Utils;
use g3\mail\MailClient;
use Firebase\JWT;

class Auth {
   /** @var AuthToken $token The AuthToken of this class */
   protected $token;
   /** @var PDO $dbh The PDO handler to the database */
   protected $dbh;
...............
...............
   /**
    * Called by user/admin during the registration.
    * 
    * We use argument '$params' to handle the additional fields that we added at 
    * table 'profiles' (beyond, 'id', 'emai', 'password', 'isactive' and 'dt'). 
    * An example for '$params': array('first_name' =&gt; &quot;John&quot;, 'second_name' =&gt; &quot;Doe&quot;).
    * The available fields:
    * - 'title', 
    * - 'fullname',
    * - 'first_name',
    * - 'second_name',
    * - 'username',
    * - 'address1',
    * - 'address2',
    * - 'zip1',
    * - 'zip2',
    * - 'tel',
    * - 'mobile',
    * - 'fax',
    * - 'city',
    * - 'state',
    * - 'country',
    * - 'birth',
    * - 'language',
    * - 'currency',
    * - 'img',
    * - 'capacity_kb'.
    * 
    * Two modes of call:
    * -by user: addUser($email, $password, $params, $name),
    * -by admin: addUser($email, $password, $params, $name, true).
    * 
    * In admin mode no request is added or email is sent.
    * 
    * If useradd succeeds but profile fails to be inserted in table 'profiles' 
    * then return array contains key 'message' although key 'error' remains 
    * 'false' (registration proceeds).
    * 
    * @param string $email
    * @param string $password
    * @param string[] $params Data for table 'profiles'
    * @param boolean $admin True to bypass activation process
    * 
    * @return A hash array with keys 'error', 'message' and if successful, 'uid'
    */
   protected function addUser($email, $password, $params = array(), $name = '', $admin = false) {
      $return['error'] = true;
      $query = $this-&gt;dbh-&gt;prepare(&quot;INSERT INTO {$this-&gt;token-&gt;get('table_users')} (isactive) VALUES (0)&quot;);
      if (!$query-&gt;execute()) {
         $return['message'] = $this-&gt;getLang()[&quot;system_error&quot;] . &quot; #03&quot;;
         return $return;
      }
      $uid = $this-&gt;dbh-&gt;lastInsertId();
      $email = \htmlentities(\strtolower($email));
      if (((int)$this-&gt;token-&gt;get('suppress_activation') != 1) &amp;&amp; !$admin) {
         $addRequest = $this-&gt;addRequest($uid, $email, &quot;activation&quot;, $name);
         if ($addRequest['error'] == 1) {
            $query = $this-&gt;dbh-&gt;prepare(&quot;DELETE FROM {$this-&gt;token-&gt;get('table_users')} WHERE id = ?&quot;);
            $query-&gt;execute(array($uid));
            $return['message'] = $addRequest['message'];
            return $return;
         }
         $isactive = 0;
      } else {
         $isactive = 1;
      }
      $password = $this-&gt;getHash($password);
      $query = $this-&gt;dbh-&gt;prepare(&quot;UPDATE {$this-&gt;token-&gt;get('table_users')} SET email = ?, password = ?, isactive = ? WHERE id = ?&quot;);
      if (!$query-&gt;execute(array($email, $password, $isactive, $uid))) {
         $query = $this-&gt;dbh-&gt;prepare(&quot;DELETE FROM {$this-&gt;token-&gt;get('table_users')} WHERE id = ?&quot;);
         $query-&gt;execute(array($uid));
         $return['message'] = $this-&gt;getLang()[&quot;system_error&quot;] . &quot; #04&quot;;
         return $return;
      }
      if (!\is_array($params))
         $params = array();
      if(($r = $this-&gt;addProfile($uid, $params)) !== true)
         $return['message'] = $r['message'];
      $return['error'] = false;
      $return['uid'] = $uid;
      return $return;
   }
.............
.............
}
</code></pre>
<p>Database is SQLite.</p>
<p>It's obvious that a numerous other methods of <code>class Auth</code> are called:</p>
<pre><code>Auth::addUser
  | | | |
  v | | |
Auth::getLang
    | | |
    v | |
Auth::addRequest
      | |
      v |
Auth::getHash
        |
        v
Auth::addProfile
</code></pre>
<p>Also a number of other classes are used:</p>
<pre><code>class Auth
  | | |
  v | |
Auth::token is a AuthToken: contains parameters supporting the 
authentication system like table names, database path etc.
    | |
    v |
class Lang: contains parameters that lead to language specific 
messages
      |
      v
Auth::dbh is a database connection returned by DbHandler::getHandler
class DbHandler: manages the database
</code></pre>
<p><strong>You can skip next parts and read &quot;5. Write some tests&quot;</strong></p>
<h1>2 Setup Composer</h1>
<ul>
<li><p>just download a local <code>composer.phar</code></p>
</li>
<li><p>build a <code>composer.json</code>: I don't care about composer's autoloader as I have mine and I load it there from my <code>/home/test/server/g3</code> sub-folder</p>
</li>
<li><p>I don't use <code>vendor</code> but only for developing packages all production software including my <code>g3</code> framework are deployed on <code>/home/test/server</code> sub-folder on seperate sub-folders with a custom autoloader</p>
</li>
</ul>
<p><em><strong>/home/test/composer.json</strong></em></p>
<pre><code>{
   &quot;autoload&quot;: {
      &quot;psr-4&quot;: {
         &quot;&quot;: &quot;server&quot;
      }
    },
   &quot;require-dev&quot;: {
         &quot;mockery/mockery&quot;: &quot;=1.3.1&quot;,
         &quot;phpunit/phpunit&quot;: &quot;=6.5.14&quot;,
         &quot;phpunit/php-invoker&quot;: &quot;=1.1.4&quot;,
         &quot;gealex/doublit&quot;: &quot;=2.1.5&quot;,
         &quot;phpspec/prophecy&quot;: &quot;=1.10.3&quot;
    }
}
</code></pre>
<p><em><strong>/home/test/vendor/autoloader.php</strong></em></p>
<pre><code>&lt;?php

// my autoloader
require_once(&quot;/home/test/server/g3/ClassLoader.php&quot;);

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit1e0ee11cc0a18a5af0d236383dd8a888::getLoader();
</code></pre>
<h1>3 Setup phpunit</h1>
<ul>
<li><p>just download a local <code>/home/test/server/dev/phpunit-6.phar</code></p>
</li>
<li><p>customize the <code>/home/test/server/dev/phpunit.xml</code></p>
</li>
</ul>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;phpunit backupGlobals=&quot;false&quot;
         backupStaticAttributes=&quot;false&quot;
         bootstrap=&quot;/home/test/vendor/autoload.php&quot;
         colors=&quot;true&quot;
         convertErrorsToExceptions=&quot;true&quot;
         convertNoticesToExceptions=&quot;true&quot;
         convertWarningsToExceptions=&quot;true&quot;
         processIsolation=&quot;false&quot;
         stopOnFailure=&quot;false&quot;
         syntaxCheck=&quot;false&quot;
         verbose=&quot;true&quot;&gt;

    &lt;testsuites&gt;
        &lt;testsuite name=&quot;Root&quot;&gt;
            &lt;directory suffix=&quot;Test.php&quot;&gt;../../tests/server/root&lt;/directory&gt;
        &lt;/testsuite&gt;

        &lt;testsuite name=&quot;Core&quot;&gt;
            &lt;directory suffix=&quot;Test.php&quot;&gt;../../tests/server/core&lt;/directory&gt;
        &lt;/testsuite&gt;

        &lt;testsuite name=&quot;Auth&quot;&gt;
            &lt;directory suffix=&quot;Test.php&quot;&gt;../../tests/server/auth&lt;/directory&gt;
        &lt;/testsuite&gt;

        &lt;testsuite name=&quot;mail&quot;&gt;
            &lt;directory suffix=&quot;Test.php&quot;&gt;../../tests/server/mail&lt;/directory&gt;
        &lt;/testsuite&gt;
    &lt;/testsuites&gt;

    &lt;filter&gt;
        &lt;whitelist processUncoveredFilesFromWhitelist=&quot;true&quot;&gt;
            &lt;directory suffix=&quot;.php&quot;&gt;server&lt;/directory&gt;
        &lt;/whitelist&gt;
    &lt;/filter&gt;

    &lt;php&gt;
        &lt;var name=&quot;skip_mail_integration_tests&quot; value=&quot;1&quot;/&gt;
        &lt;var name=&quot;skip_auth_integration_tests&quot; value=&quot;1&quot;/&gt;
        &lt;var name=&quot;domain&quot; value=&quot;4f4d4ebc35f1.eu.ngrok.io&quot;/&gt;
        &lt;var name=&quot;mailTo&quot; value=&quot;john.doe@gmail.com&quot;/&gt;
    &lt;/php&gt;
&lt;/phpunit&gt;
</code></pre>
<h1>4 Extend PHPUnit\Framework\TestCase</h1>
<p>First let's extend <code>PHPUnit\Framework\TestCase</code> with <code>/home/test/tests/server/CustomTestCase.php</code> that</p>
<ul>
<li><p>supports <code>Prophecy</code> and <code>Mockery</code></p>
</li>
<li><p>contains utility methods <code>callMethod</code>, <code>getProperty</code> and <code>setProperty</code> that can access private/protected members</p>
</li>
<li><p>initializes <code>\g3\Registry</code> with real <code>\g3\Token</code> values coming from json files</p>
</li>
</ul>
<pre><code>&lt;?php
declare(strict_types=1);

use Mockery\Adapter\Phpunit\MockeryTestCase;
use PHPUnit\Framework\TestCase;

/**
 * runTestsInSeparateProcesses
 */
class CustomTestCase extends MockeryTestCase {
   protected $prophet;
   
   // returns the call to private/protected methods
   public static function callMethod($obj, $name, array $args) {
      $class = new \ReflectionClass($obj);
      $method = $class-&gt;getMethod($name);
      $method-&gt;setAccessible(true);
      return $method-&gt;invokeArgs($obj, $args);
   }
   // returns private/protected properties
   public static function getProperty($obj, $name){
      $r = new ReflectionObject($obj);
      $p = $r-&gt;getProperty($name);
      $p-&gt;setAccessible(true);
      return $p-&gt;getValue($obj);
      // alternative syntax with closures
      //$cls = \Closure::bind(function() use ($name){return $this-&gt;{$name};}, $obj, \get_class($obj));
      //return $cls();
   }
   // sets a value to a private/protected property
   public static function setProperty($object, $property, $value){
       $ref = new \ReflectionClass($object);
       $ref_prop = $ref-&gt;getProperty($property);
       $ref_prop-&gt;setAccessible(true);
       $ref_prop-&gt;setValue($object, $value);
   }
   
   public static function setUpBeforeClass(){
      Mockery::globalHelpers();
   }
   public static function tearDownAfterClass(){
   }
   
   protected function setup() {
      $this-&gt;prophet = new \Prophecy\Prophet;
   }
   protected function tearDown() {
      $this-&gt;prophet-&gt;checkPredictions();
      Mockery::close();
   }
}
</code></pre>
<h1>5 Write some tests</h1>
<p>File is <code>/home/test/tests/server/g3/auth/AuthTest.php</code></p>
<pre><code>&lt;?php
declare(strict_types=1);

require_once(__DIR__ . '/../CustomTestCase.php');

/**
 * runTestsInSeparateProcesses
 */
class AuthTest extends CustomTestCase {
   protected $tokens;
   
   public static function setUpBeforeClass(){
      parent::setUpBeforeClass();
      // tokens initialize the g3 framework and these contain full data 
      // from json files; access them like: 
      // \g3\Registry::getInstance()-&gt;getToken('g3\auth\AuthToken') etc.
      static::callMethod(\g3\Dispatcher::getInstance(), 'tokenInit', array());
   }
   public static function tearDownAfterClass(){
      parent::tearDownAfterClass();
      \g3\Registry::getInstance()-&gt;destroy();
   }
   
   /**
    * Creates mocked constructor argument objects before each test.
    * These tokens do not contain data read from json files; dummy tokens.
    * Accessible through $this-&gt;tokens.
    */
   protected function setup() {
      parent::setup();
      
      $resolverToken = $this-&gt;getMockBuilder('\g3\ResolverToken')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $requestToken = $this-&gt;getMockBuilder('\g3\RequestToken')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $authToken = $this-&gt;getMockBuilder('\g3\auth\AuthToken')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $accountToken = $this-&gt;getMockBuilder('\g3\AccountToken')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $dbh = $this-&gt;getMockBuilder('\g3\DbHandler')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $lang = $this-&gt;getMockBuilder('\g3\Lang')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $session = $this-&gt;getMockBuilder('\g3\Session')
         -&gt;disableOriginalConstructor()
         -&gt;getMock();
      
      $this-&gt;tokens = array('accountToken' =&gt; $accountToken, 'resolverToken' =&gt; $resolverToken, 'requestToken' =&gt; $requestToken, 'authToken' =&gt; $authToken, 'dbh' =&gt; $dbh, 'lang' =&gt; $lang, 'session' =&gt; $session);
   }
   
   /**
    * Deletes mocked objects stored at $this-&gt;tokens after each test.
    */
   protected function tearDown() {
      parent::tearDown();
      $this-&gt;tokens = null;
   }
   
   /**
    * Prints a message on CLI
    */
   public function out($msg){
      $msg = \str_replace(array('test_', '_', &quot;\n&quot;), array('', ' ', &quot;:\n&quot;), $msg);
      fwrite(STDOUT, $msg);
   }

   /**
    * Adds an inactive user. It uses real tokens.
    */
   public function helper_addUserInactive($arr) {
      // AuthToken is not stored in Registry &amp; not synchronized
      \g3\TokenFactory::getInstance()-&gt;synchronize($arr['authToken'], 'r');
      $test = $this-&gt;getMockBuilder('\g3\auth\Auth')
         -&gt;setConstructorArgs(array($arr['resolverToken'], $arr['requestToken'], $arr['authToken'], $arr['accountToken'], $arr['dbh']))
         -&gt;setMethods(['addRequest', 'getHash'])
         -&gt;getMock();
      $test-&gt;expects($this-&gt;exactly(1))
         -&gt;method('addRequest')
         -&gt;will($this-&gt;returnValue(array('error' =&gt; false)));
      $test-&gt;expects($this-&gt;exactly(1))
         -&gt;method('getHash')
         -&gt;will($this-&gt;returnValue('123'));
      $token = static::getProperty($test, 'token');
      $token-&gt;set('suppress_activation', 0);
      $profile = array('first_name' =&gt; 'John', 'second_name' =&gt; 'Doe', 'username' =&gt; 'John', 'address1' =&gt; 'White House, Washington D.C.', 'country' =&gt; 'USA');
      // call 'addUser'
      $r = static::callMethod($test, 'addUser', array($arr['to'], '123', $profile, 'John'));
      $users = $arr['authToken']-&gt;get('table_users');
      $profiles = $arr['authToken']-&gt;get('table_profiles');
      
      return array(
         'dbh' =&gt; $arr['dbh'], 
         'user' =&gt; array('id' =&gt; $r['uid'], 'email' =&gt; $arr['to'], 'password' =&gt; '123', 'role' =&gt; 'guest', 'isactive' =&gt; '0'), 
         'profile' =&gt; $profile, 
         'tables' =&gt; array('users' =&gt; $arr['authToken']-&gt;get('table_users'), 'profiles' =&gt; $arr['authToken']-&gt;get('table_profiles'), 'requests' =&gt; $arr['authToken']-&gt;get('table_requests'))
      );
   }

/**
    * Adds an active user. It uses real tokens.
    */
   public function helper_addUserActive($arr) {
      // AuthToken is not stored in Registry &amp; not synchronized
      \g3\TokenFactory::getInstance()-&gt;synchronize($arr['authToken'], 'r');
      $test = $this-&gt;getMockBuilder('\g3\auth\Auth')
         -&gt;setConstructorArgs(array($arr['resolverToken'], $arr['requestToken'], $arr['authToken'], $arr['accountToken'], $arr['dbh']))
         -&gt;setMethods(['addRequest', 'getHash'])
         -&gt;getMock();
      $test-&gt;expects($this-&gt;never())
         -&gt;method('addRequest');
      $test-&gt;expects($this-&gt;exactly(1))
         -&gt;method('getHash')
         -&gt;will($this-&gt;returnValue('123'));
      $token = static::getProperty($test, 'token');
      $token-&gt;set('suppress_activation', 1);
      $profile = array('first_name' =&gt; 'John', 'second_name' =&gt; 'Doe', 'username' =&gt; 'John', 'address1' =&gt; 'White House, Washington D.C.', 'country' =&gt; 'USA');
      // call 'addUser'
      $r = static::callMethod($test, 'addUser', array($arr['to'], '123', $profile, 'John'));
      $users = $arr['authToken']-&gt;get('table_users');
      $profiles = $arr['authToken']-&gt;get('table_profiles');
      
      return array(
         'dbh' =&gt; $arr['dbh'], 
         'user' =&gt; array('id' =&gt; $r['uid'], 'email' =&gt; $arr['to'], 'password' =&gt; '123', 'role' =&gt; 'guest', 'isactive' =&gt; '1'), 
         'profile' =&gt; $profile, 
         'tables' =&gt; array('users' =&gt; $arr['authToken']-&gt;get('table_users'), 'profiles' =&gt; $arr['authToken']-&gt;get('table_profiles'), 'requests' =&gt; $arr['authToken']-&gt;get('table_requests'))
      );
   }
   
   /**
    * Adds an active user as admin. It uses real tokens.
    */
   public function helper_adminAddsUserActive($arr) {
      // AuthToken is not stored in Registry &amp; not synchronized
      \g3\TokenFactory::getInstance()-&gt;synchronize($arr['authToken'], 'r');
      $test = $this-&gt;getMockBuilder('\g3\auth\Auth')
         -&gt;setConstructorArgs(array($arr['resolverToken'], $arr['requestToken'], $arr['authToken'], $arr['accountToken'], $arr['dbh']))
         -&gt;setMethods(['addRequest', 'getHash'])
         -&gt;getMock();
      $test-&gt;expects($this-&gt;never())
         -&gt;method('addRequest');
      $test-&gt;expects($this-&gt;exactly(1))
         -&gt;method('getHash')
         -&gt;will($this-&gt;returnValue('123'));
      $token = static::getProperty($test, 'token');
      $token-&gt;set('suppress_activation', 0);
      $profile = array('first_name' =&gt; 'John', 'second_name' =&gt; 'Doe', 'username' =&gt; 'John', 'address1' =&gt; 'White House, Washington D.C.', 'country' =&gt; 'USA');
      // call 'addUser'
      $r = static::callMethod($test, 'addUser', array($arr['to'], '123', $profile, 'John', true));
      $users = $arr['authToken']-&gt;get('table_users');
      $profiles = $arr['authToken']-&gt;get('table_profiles');
      
      return array(
         'dbh' =&gt; $arr['dbh'], 
         'user' =&gt; array('id' =&gt; $r['uid'], 'email' =&gt; $arr['to'], 'password' =&gt; '123', 'role' =&gt; 'guest', 'isactive' =&gt; '1'), 
         'profile' =&gt; $profile, 
         'tables' =&gt; array('users' =&gt; $arr['authToken']-&gt;get('table_users'), 'profiles' =&gt; $arr['authToken']-&gt;get('table_profiles'), 'requests' =&gt; $arr['authToken']-&gt;get('table_requests'))
      );
   }
   
   /**
    * Inserts a user &amp; profile without the call to any `Auth` method.
    * It uses real tokens.
    */
   public function helper_insertUser($arr, $active = '0') {
      // AuthToken is not stored in Registry &amp; not synchronized
      \g3\TokenFactory::getInstance()-&gt;synchronize($arr['authToken'], 'r');
      $users = $arr['authToken']-&gt;get('table_users');
      $profiles = $arr['authToken']-&gt;get('table_profiles');
      $requests = $arr['authToken']-&gt;get('table_requests');
      // table 'users'
      $time = \time();
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;INSERT INTO {$users} (email, password, isactive, dt) VALUES (?, ?, ?, ?)&quot;);
      $query-&gt;execute(array($arr['to'], '123', $active, $time));
      $uid = $arr['dbh']-&gt;getHandler()-&gt;lastInsertId();
      return array(
         'dbh' =&gt; $arr['dbh'], 
         'user' =&gt; array('id' =&gt; $uid, 'email' =&gt; $arr['to'], 'password' =&gt; '123', 'role' =&gt; 'guest', 'isactive' =&gt; $active),  
         'tables' =&gt; array('users' =&gt; $users, 'profiles' =&gt; $profiles, 'requests' =&gt; $requests)
      );
   }

   /**
    * Deletes user from tables `users`, `profiles` and `requests`.
    * `$arr` is the return of `::test_helper_addUserInactive` or 
    * `::test_helper_addUserActive`.
    */
   public function helper_deleteAddedUser($arr) {
      $users = $arr['tables']['users'];
      $profiles = $arr['tables']['profiles'];
      $requests = $arr['tables']['requests'];
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;DELETE FROM {$users} WHERE id = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;DELETE FROM {$profiles} WHERE uid = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;DELETE FROM {$requests} WHERE uid = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
   }

   /**
    * Helper that returns real tokens of g3 platform.
    * @group integration_email
    * @group test
    */
   public function test_helper_construct_with_real_tokens() {
      $systemToken = \g3\Registry::getInstance()-&gt;getToken('g3\SystemToken');
      $accountToken = \g3\Registry::getInstance()-&gt;getToken('g3\AccountToken');
      $lang = new \g3\Lang(ROOT . &quot;/server/g3/auth/language&quot;, $accountToken-&gt;get('site', 'language'));
      $exceptionToken = \g3\Registry::getInstance()-&gt;getToken('g3\ExceptionToken');
      $dbh = new \g3\DbHandler('sqlite', 'db_auth', $accountToken, $exceptionToken);
      // AuthToken is not stored in Registry &amp; not synchronized
      $authToken = \g3\TokenFactory::getInstance()-&gt;getToken('g3\auth\AuthToken', null, array('registry' =&gt; \g3\Registry::getInstance(), 'dbh' =&gt; $dbh));
      \g3\TokenFactory::getInstance()-&gt;synchronize($authToken, 'r');
      $requestToken = \g3\Registry::getInstance()-&gt;getToken('g3\RequestToken');
      $resolverToken = \g3\Registry::getInstance()-&gt;getToken('g3\ResolverToken');
      $session = \g3\Session::getInstance();
      $to = $GLOBALS['mailTo'];
      
      $this-&gt;assertTrue(true);
      
      return array('systemToken' =&gt; $systemToken, 'accountToken' =&gt; $accountToken, 'resolverToken' =&gt; $resolverToken, 'requestToken' =&gt; $requestToken, 'authToken' =&gt; $authToken, 'exceptionToken' =&gt; $exceptionToken, 'dbh' =&gt; $dbh, 'lang' =&gt; $lang, 'session' =&gt; $session, 'to' =&gt; $to);
   }

   // !!!WAIT WHAT THE HELL!!!
   // !!!WE DIDN'T EVEN BEGIN TO TEST!!!

   /*
    * ===============
    * Auth::addUser()
    * ===============
    */
   /**
    * @depends test_helper_construct_with_real_tokens
    */
   public function test_addUser_for_misspelled_table_users($arr) {
      $this-&gt;out(__METHOD__ . &quot;\n&quot;);
      // AuthToken is not stored in Registry &amp; not synchronized
      \g3\TokenFactory::getInstance()-&gt;synchronize($arr['authToken'], 'r');
      $test = $this-&gt;getMockBuilder('\g3\auth\Auth')
         -&gt;setConstructorArgs(array($arr['resolverToken'], $arr['requestToken'], $arr['authToken'], $arr['accountToken'], $arr['dbh']))
         -&gt;setMethods(null)
         -&gt;getMock();
      $token = static::getProperty($test, 'token');
      $token-&gt;set('table_users', 'user');
      // call 'addUser'
      $this-&gt;expectException(PDOException::class);
      $r = static::callMethod($test, 'addUser', array($arr['to'], '123', array(), 'John'));
      echo &quot;\n&quot;;
   }
   /**
    * @depends test_helper_construct_with_real_tokens
    */
   public function test_addUser_updates_tables_users_profiles($tokens) {
      $this-&gt;out(__METHOD__ . &quot;\n&quot;);
      $arr = $this-&gt;helper_addUserInactive($tokens);
      $users = $arr['tables']['users'];
      $profiles = $arr['tables']['profiles'];
      // query table 'users'
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;SELECT email, role, password, isactive FROM $users WHERE id = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $row = $query-&gt;fetch(\PDO::FETCH_ASSOC);
      $this-&gt;assertSame($arr['user']['email'], $row['email']);
      $this-&gt;assertSame($arr['user']['role'], $row['role']);
      $this-&gt;assertSame($arr['user']['password'], $row['password']);
      $this-&gt;assertSame($arr['user']['isactive'], $row['isactive']);
      // query table 'profiles'
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;SELECT first_name, second_name, username, address1 FROM $profiles WHERE uid = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $row = $query-&gt;fetch(\PDO::FETCH_ASSOC);
      $this-&gt;assertSame($arr['profile']['first_name'], $row['first_name']);
      $this-&gt;assertSame($arr['profile']['second_name'], $row['second_name']);
      $this-&gt;assertSame($arr['profile']['username'], $row['username']);
      $this-&gt;assertSame($arr['profile']['address1'], $row['address1']);
      // delete entries in tables
      $this-&gt;test_helper_deleteAddedUser($arr);
      echo &quot;\n&quot;;
   }
   /**
    * @depends test_helper_construct_with_real_tokens
    */
   public function test_addUser_updates_tables_users_profiles_with_supress_activation($tokens) {
      $this-&gt;out(__METHOD__ . &quot;\n&quot;);
      $arr = $this-&gt;helper_addUserActive($tokens);
      $users = $arr['tables']['users'];
      $profiles = $arr['tables']['profiles'];
      // query table 'users'
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;SELECT email, role, password, isactive FROM $users WHERE id = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $row = $query-&gt;fetch(\PDO::FETCH_ASSOC);
      $this-&gt;assertSame($arr['user']['email'], $row['email']);
      $this-&gt;assertSame($arr['user']['role'], $row['role']);
      $this-&gt;assertSame($arr['user']['password'], $row['password']);
      $this-&gt;assertSame($arr['user']['isactive'], $row['isactive']);
      // query table 'profiles'
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;SELECT first_name, second_name, username, address1 FROM $profiles WHERE uid = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $row = $query-&gt;fetch(\PDO::FETCH_ASSOC);
      $this-&gt;assertSame($arr['profile']['first_name'], $row['first_name']);
      $this-&gt;assertSame($arr['profile']['second_name'], $row['second_name']);
      $this-&gt;assertSame($arr['profile']['username'], $row['username']);
      $this-&gt;assertSame($arr['profile']['address1'], $row['address1']);
      // delete entries in tables
      $this-&gt;test_helper_deleteAddedUser($arr);
      echo &quot;\n&quot;;
   }
   /**
    * @depends test_helper_construct_with_real_tokens
    */
   public function test_addUser_updates_tables_users_profiles_for_admin($tokens) {
      $this-&gt;out(__METHOD__ . &quot;\n&quot;);
      $arr = $this-&gt;helper_adminAddsUserActive($tokens);
      $users = $arr['tables']['users'];
      $profiles = $arr['tables']['profiles'];
      // query table 'users'
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;SELECT email, role, password, isactive FROM $users WHERE id = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $row = $query-&gt;fetch(\PDO::FETCH_ASSOC);
      $this-&gt;assertSame($arr['user']['email'], $row['email']);
      $this-&gt;assertSame($arr['user']['role'], $row['role']);
      $this-&gt;assertSame($arr['user']['password'], $row['password']);
      $this-&gt;assertSame($arr['user']['isactive'], $row['isactive']);
      // query table 'profiles'
      $query = $arr['dbh']-&gt;getHandler()-&gt;prepare(&quot;SELECT first_name, second_name, username, address1 FROM $profiles WHERE uid = ?&quot;);
      $query-&gt;execute(array($arr['user']['id']));
      $row = $query-&gt;fetch(\PDO::FETCH_ASSOC);
      $this-&gt;assertSame($arr['profile']['first_name'], $row['first_name']);
      $this-&gt;assertSame($arr['profile']['second_name'], $row['second_name']);
      $this-&gt;assertSame($arr['profile']['username'], $row['username']);
      $this-&gt;assertSame($arr['profile']['address1'], $row['address1']);
      // delete entries in tables
      $this-&gt;test_helper_deleteAddedUser($arr);
      echo &quot;\n&quot;;
   }
</code></pre>
<p>I just tested sth I knew from the beginning - several months ago - it was working o'right as I can send GET or POST requests and with injected <code>error_log</code> I have production error-free code bypassing all unit-testing theories.</p>
<p>Also these tests are prone to error if someone starts messing with the testing method they start producing code errors from the test file; in that case you have to debug the tests that try to test your code!</p>
<p><strong>From my point of view I start to believe that unit-testing is an excellent way to waste <s>loose</s> your time.</strong> I understand your argument that this is not unit testing so I replace <code>protected</code> with <code>public</code> does that fixes anything?
I wonder can someone prove me wrong? What's your approach then?</p>
",https://stackoverflow.com/questions/62831163/best-practices-of-phpunit-in-a-complex-scenario,"['php', 'unit-testing', 'phpunit']",720,False,0,1
How to debug &quot;Jest has detected the following ... open handle potentially keeping Jest from exiting&quot;,"<p>I am having further problems with async code in Jest. My <a href=""https://stackoverflow.com/questions/61637311/how-to-ensure-the-jest-bootstrap-file-is-run-first"">previous question</a> (for the same project) was related to running async code in a Jest bootstrap. My new issue relates to running async database calls within the tests. My aim is to connect to database services and to make calls to make sure they read and write to the database correctly. I have the tests running in one Docker container, connecting to a MySQL instance in another container.</p>

<p>I am using the <code>mysql2/promise</code> Node library, which as the same suggests, wraps callback-based database operations in a Promise. Most of the operations are async, except for connection closing (and a few others). Indeed, I wonder if this is relevant.</p>

<p>I should start with some code. Here is my test:</p>

<pre><code>import TestDatabase from '../TestDatabase';
var config = require('../../config/config.json');
import FetchDonations from ""../../src/services/FetchDonations"";
const envName = 'test';

let database = new TestDatabase(config);

// Connect before all tests
beforeAll(() =&gt; {
  console.log('Connect Jest database');
  return database.connect(envName);
});

// Disconnect after all tests
afterAll(async done =&gt; {
  console.log('Disconnect Jest database');
  database.close();
  done();
});

describe('Database tests', () =&gt; {

  // Before every test
  beforeEach(() =&gt; database.beforeEachTest(envName));

  test('Describe this demo test', () =&gt; {
    console.log('Test #1');
    expect(true).toEqual(true);
  });

  test('Describe this demo test 2', () =&gt; {
    console.log('Test #2');
    expect(true).toEqual(true);
  });

});
</code></pre>

<p>This just runs a couple of dummy tests. They don't do anything, I'm just trying to get the before/after hooks working. These are what they should do:</p>

<ul>
<li>beforeAll - connect to the database once (asynchronous op)</li>
<li>afterAll - disconnect from the database once (synchronous op in mysql2)</li>
<li>beforeEach - run <code>database.beforeEachTest()</code> before every test, this truncates the tables in the database (asynchronous ops)</li>
</ul>

<p>Here is what <code>TestDatabase</code> looks like - these are utility methods I've written to help with database testing:</p>

<pre><code>const mysql = require('mysql2/promise');

export default class TestDatabase {

  constructor(config) {
    this.config = config;
  }

  beforeEachTest(environmentName) {
    console.log('Before a test');

    return this.setForeignKeyChecks(false).then(() =&gt; {
      return this.truncateTables();
    }).then(() =&gt; {
      return this.setForeignKeyChecks(true);
    }).catch((error) =&gt; {
      console.log('Failed to clear down database: ' + error);
    });
  }

  connect(environmentName) {
    const config = this.getEnvConfig(environmentName);

    return mysql.createConnection({
      host: config.host, user: config.username,
      password: config.password
    }).then((connection) =&gt; {
      this.connection = connection;
      return this.useDatabase(environmentName);
    }).catch((error) =&gt; {
      console.log('Failed to connect to the db');
    });
  }

  getConnection() {
    if (!this.connection) {
      throw 'Database not connected';
    }

    return this.connection;
  }

  dropDatabase(environmentName) {
    const config = this.getEnvConfig(environmentName);

    return this.getConnection().query(
      `DROP DATABASE IF EXISTS ${config.database}`
    );
  }


  createDatabase(environmentName) {
    const config = this.getEnvConfig(environmentName);

    return this.getConnection().query(
      `CREATE DATABASE IF NOT EXISTS ${config.database}`
    );
  }

  useDatabase(environmentName) {
    const config = this.getEnvConfig(environmentName);

    return this.getConnection().query(
      `USE ${config.database}`
    );
  }

  setForeignKeyChecks(value) {
    // Make injected value safe
    var boolStr = value ? '1' : '0';

    return this.getConnection().query(
      `SET FOREIGN_KEY_CHECKS = ${boolStr}`
    );
  }

  getTables() {
    return ['contribution', 'donation', 'expenditure',
      'tag', 'expenditure_tag'];
  }

  truncateTables() {
    return Promise.all(
      this.getTables().map(table =&gt; this.truncateTable(table))
    );
  }

  truncateTable(table) {
    return this.getConnection().query(
      `TRUNCATE TABLE ${table}`
    );
  }

  /**
   * Close is synchronous so there is no returned promise
   */
  close() {
    this.getConnection().close();
  }

  getEnvConfig(environmentName) {
    if (!environmentName) {
      throw 'Please supply an environment name'
    }
    if (!this.config[environmentName]) {
      throw 'Cannot find database environment data'
    }

    return this.config[environmentName];
  }
}
</code></pre>

<p>Now, if I run the tests, they pass and finish, but there are two oddities. Firstly, the some of the async console.log output is being output after the test summary, so I think I am not handling async in the way Jest wants it. In other words, I think the summary should be rendered after all of this:</p>

<pre><code>/project/node_modules/.bin/jest tests
  console.log
    Connect Jest database

      at Object.&lt;anonymous&gt; (tests/database/TestDemo.test.js:29:11)

  console.log
    Before a test

      at TestDatabase.beforeEachTest (tests/TestDatabase.js:10:13)

 PASS  tests/database/TestDemo.test.js
  Database tests
    ✓ Describe this demo test (72ms)
    ✓ Describe this demo test 2 (58ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.118s, estimated 3s
Ran all test suites matching /tests/i.
  console.log
    Test #1

      at Object.&lt;anonymous&gt; (tests/database/TestDemo.test.js:46:13)

  console.log
    Before a test

      at TestDatabase.beforeEachTest (tests/TestDatabase.js:10:13)

  console.log
    Test #2

      at Object.&lt;anonymous&gt; (tests/database/TestDemo.test.js:51:13)

  console.log
    Disconnect Jest database

      at _callee$ (tests/database/TestDemo.test.js:35:11)
</code></pre>

<p>As you can see, output from both Tests appears after the summary, but output from the <code>beforeEach</code> for the first test appears before the test summary.</p>

<p>Moreover, if I add real tests that use the database, I get errors saying that I have unhandled promises, and that I should try Jest's unhandled promise detector (<code>--detectOpenHandles</code>). Moreover, in that situation, Jest stops in a loop and needs ^C to give the console prompt back.</p>

<p>So, I am trying <code>--detectOpenHandles</code> with the current code, and although I don't get a Jest freeze, I get the following.</p>

<pre><code>Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  TCPWRAP

      22 |     const config = this.getEnvConfig(environmentName);
      23 | 
    &gt; 24 |     return mysql.createConnection({
         |                  ^
      25 |       host: config.host, user: config.username,
      26 |       password: config.password
      27 |     }).then((connection) =&gt; {

      at new Connection (node_modules/mysql2/lib/connection.js:35:27)
      at Object.&lt;anonymous&gt;.exports.createConnection (node_modules/mysql2/index.js:10:10)
      at Object.createConnection (node_modules/mysql2/promise.js:230:31)
      at TestDatabase.connect (tests/TestDatabase.js:24:18)
      at Object.&lt;anonymous&gt; (tests/database/TestDemo.test.js:30:19)

</code></pre>

<p>My view is that this is directly connected to the freeze I get with more tests, and that I should fix that before attempting to add more tests.</p>

<p>I have been through several investigation loops to determine what might cause this, and the code has been tweaked several times:</p>

<ul>
<li><code>afterAll</code> and <code>beforeEach</code> are async ops, so they need to be <code>return</code>ed to Jest, so Jest knows to wait for them to resolve.</li>
<li><code>afterAll</code> does a db close, but this is not async, so I am using Jest's <code>done()</code> here, though it also did not work if it is done without <code>done()</code>.</li>
<li><code>TestDatabase</code> contains two main methods, <code>beforeEachTest</code> and <code>connect</code>, and I have been very careful to ensure they return Promises.</li>
<li>I have tended towards chained thenables, rather than async-await, as it feels clearer to me. However I have tried async-await in several areas, and it did not help.</li>
<li>Utility code like <code>dropDatabase</code>, <code>createDatabase</code>, <code>setForeignKeyChecks</code>, <code>truncateTables</code>, <code>truncateTable</code> all return Promises.</li>
<li>I've read the <a href=""https://jestjs.io/docs/en/asynchronous"" rel=""noreferrer"">Jest async docs</a> and there are a lot of approaches. The main takeaway is that if you are testing something async, the promise should be returned to Jest, so the appropriate waiting is done. My real tests are synchronous, it's just my before hooks that are async. Thinking about it, I wonder if that is the problem?</li>
</ul>

<p>I am fairly new to Jest, and not too experienced in JS async either. Every time I think I have an improved understanding of async, I get a fresh curveball. However, I wonder if this is more Jest oddities, rather than a difficulty understanding raw async.</p>
",https://stackoverflow.com/questions/61689307/how-to-debug-jest-has-detected-the-following-open-handle-potentially-keepin,"['javascript', 'node.js', 'asynchronous', 'jestjs', 'node-mysql2']",8418,True,5,3
