Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / PHP

Unit Tests for Symfony Entity Classes

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
31 Dec 2018CPOL3 min read 5.4K   2  
Unit tests for Symfony Entity classes

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:

PHP
// tests/AppBundle/Entity/UserTest.php
namespace tests\AppBundle\Entity;

use AppBundle\Entity\User;
use PHPUnit\Framework\TestCase;

class UserTest extends TestCase{
public function testUserCreate(){
$user = new User();	// Create User object.
...
}
}

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:

Eclipse User object outline

Now let’s test the setUserName method and use the getUserName to verify, so I’ve added the test code as follows:

PHP
public function testUserCreate(){
$user = new User(); // Create User object.
$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:

Basic Test

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:

PHP
public function testUserCreate(){
$user = new User();	// Create User object.
$user->setUserName("Name");
$user->setUserType("Advisor");
$user->setFosUsername("FOS");
$user->setDivision("DIV");
$user->setDivAlt("DIV_ALT");

$sig = new Signature();   // Create a 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 );    // Remove the signature.
$sigCollection = $user->getUSignatures();
$this->assertEquals(true, $sigCollection->isEmpty());
}

and here is the completed test case for testing adding a signature to a user:

PHP
public function testAddSignature(){
$user = new User();	// Create User object.
$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:

Basic Test

Enjoy!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Taft College
United States United States
I’m a software developer. Currently I’m working at Taft College as a Programmer.

Comments and Discussions

 
-- There are no messages in this forum --