Introduction
It’s a good idea to write unit tests for each of your Symfony Entity (Doctrine) classes that are part of your Symfony project. In this article, I will show an example of unit tests that I created for the “User
” Entity, which represents a user in a petition system that I created for Taft College.
Creating Your Test File
As part of any Symfony project, test cases should be stored under the folder “tests”. The folder can also be specified in the “phpunit.xml.dist” file within the “testsuite
” tags. So for an Entity
, a good folder path to use is:
tests\AppBundle\Entity
Then in my case, I created the file “UserTest.php” under the above folder.
Test Case File
All PHPUnit
test classes should extend “PHPUnit\Framework\TestCase”; so to start a minimal file would contain the following:
namespace tests\AppBundle\Entity;
use AppBundle\Entity\User;
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase{
public function testUserCreate(){
$user = new User();
...
}
}
The above code simply just creates a User
object and does nothing else. So at this point, we need to look at what methods the User
class has and add each method (if possible) to our test case(s).
Below is a screen shot of the outline (in Eclipse) of what the User Entity looks like:
Now let’s test the setUserName
method and use the getUserName
to verify, so I’ve added the test code as follows:
public function testUserCreate(){
$user = new User();
$user->setUserName("Name");
$this->assertEquals("Name", $user->getUserName());
}
So next, let’s test it to see that everything works correctly, and we are on the right track.
Running PHPUnit
In the current releases of Symfony, you need to run PHPUnit with the following command from the top level directory of your Symfony project:
./vendor/bin/phpunit
That command by itself is not very useful. I suggest using coverage and also just specifying the single test case we’ve created, since we just want to verify this one only is working. If you get too many error/debug messages, it will be hard to troubleshoot. So to run the above test case file only and view coverage, use the following command:
./vendor/bin/phpunit --coverage-text tests/AppBundle/Entity/UserTest.php
When the above runs (normally), it shows the version of PHPUnit
, the number of tests/assertions, and in color the coverage (green is good). Below is a screenshot of what the result (normal) looks like:
This result shows that 3 of the 15 methods of the User
class have been called, which is not very much. For test cases, we need to aim for 100% of the methods tested if possible.
Final Test Cases
I ended up creating two test cases in total, since a User
needs to add a signature in the application I created, it was important to split that out into a second test case for adding the signature to the User
. This still tests the User
functionality.
Here is the completed test case for creating a User
:
public function testUserCreate(){
$user = new User();
$user->setUserName("Name");
$user->setUserType("Advisor");
$user->setFosUsername("FOS");
$user->setDivision("DIV");
$user->setDivAlt("DIV_ALT");
$sig = new Signature();
$sig->setSigType("Advisor_Submit");
$date = date("Y-m-d H:i:s", strtotime('2018-12-31 09:20:35'));
$sig->setSigDate( $date );
$user->addSignature( $sig );
$this->assertEquals("Name", $user->getUserName());
$this->assertEquals("Advisor", $user->getUserType());
$this->assertEquals("FOS", $user->getFosUsername());
$this->assertEquals("DIV", $user->getDivision());
$this->assertEquals("DIV_ALT", $user->getDivAlt());
$this->assertEquals(null, $user->getUserId());
$sigCollection = $user->getUSignatures();
$this->assertEquals($date, $sigCollection->last()->getSigDate());
$user->removeUSignature( $sig );
$sigCollection = $user->getUSignatures();
$this->assertEquals(true, $sigCollection->isEmpty());
}
and here is the completed test case for testing adding a signature to a user:
public function testAddSignature(){
$user = new User();
$user->setUserType("Advisor");
$sig = new Signature();
$sig->setSigType("Advisor_Submit");
$date = date("Y-m-d H:i:s", strtotime('2018-12-31 09:20:35'));
$sig->setSigDate( $date );
$sig->setRecommend("yes");
$sig->setSigExplain("sig_explanation");
$sig->setUser( $user );
$sig->setNotes("some_Notes");
$user->addSignature($sig);
$sigs = $user->getUSignatures();
$this->assertNotEmpty($sigs);
foreach ($sigs as $s){
$this->assertEquals("Advisor_Submit", $s->getSigType());
$this->assertEquals($date, $s->getSigDate());
$this->assertEquals("yes", $s->getRecommend());
$this->assertEquals("sig_explanation", $s->getSigExplain());
$this->assertEquals($user, $s->getUser());
$this->assertEquals("some_Notes", $s->getNotes());
$this->assertEquals(null, $s->getSigId());
}
$sig->removeUser( $user );
$s2 = $user->getUSignatures();
$this->assertEmpty($s2);
}
Note: that when I was creating the test case for adding the signature, I realized that I couldn’t just simply use the method setUser
(null
) to remove a User
; so instead I had to a add a method called “removeUser
” which removes the User
properly. Sometimes, you may have to do this when you are reviewing your code and making test cases.
After adding all the test cases for all the methods, the resultant output looks like the following:
Enjoy!