setUp() & tearDown()
setUp()
:We can use this function to write any logic that we want to executebefore
each test case function runs.tearDown()
:We can write the logic that we want to runafter
each test case function in this function.- Example:
<?php
namespace Tests\Unit;
use App\Services\TestService;
use PHPUnit\Framework\TestCase;
class TestServiceTest extends TestCase
{
private $service;
public function setUp(): void
{
$this->service = app(TestService::class);
parent::setUp();
}
public function testCanCalcuateBmi()
{
$bmiActual = $this->service->calculateBmi(1.6, 64.0);
$bmiExpected = 64.0/(1.6*1.6);
$this->assertEquals($bmiExpected, $bmiActual);
}
public function tearDown(): void
{
parent::tearDown();
$this->service = null;
}
}
In the above code, setUp()
is called before each test case function is executed, initializing $this->service
; tearDown()
is called after each test case function is executed, cleaning up $this->service
.
setUpBeforeClass() & tearDownAfterClass()
setUpBeforeClass()
:Similar to setUp(), but it will only be executedbefore the first test case function
of each test class is executed.tearDownAfterClass()
:Similar totearDown()
, but it will only be executedafter the first test case function
in each test class is executed.- Example:
<?php
namespace Tests\Unit;
use App\Services\TestService;
use PHPUnit\Framework\TestCase;
class TestServiceTest extends TestCase
{
private $service;
private static $flag;
public static function setUpBeforeClass(): void
{
self::$flag = true;
parent::setUpBeforeClass();
}
public function setUp(): void
{
$this->service = app(TestService::class);
parent::setUp();
}
public function testCanThrowExceptionWhenInvaliHeight()
{
$this->expectException(Exception::class);
$this->service->calculateBmi(0.0, 1.0);
}
public function testCanThrowExceptionWhenInvaliWeight()
{
$this->expectException(Exception::class);
$this->service->calculateBmi(1.0, 0.0);
}
public function testCanThrowExceptionWithMessageWhenInvaliData()
{
$this->expectExceptionMessage('Invalid');
$this->service->calculateBmi(0.0, 1.0);
}
public function testCanThrowExceptionWithMessageRegexMatcchWhenInvaliData()
{
$this->expectExceptionMessageMatches('/Invalid/');
$this->service->calculateBmi(0.0, 1.0);
}
public function testCanThrowExceptionWithCodeWhenInvaliData()
{
$this->expectExceptionCode(1);
$this->service->calculateBmi(0.0, 1.0);
}
public function tearDown(): void
{
parent::tearDownAfterClass();
$this->service = null;
}
public static function tearDownAfterClass(): void
{
self::$flag = false;
parent::tearDownAfterClass();
}
}
Special attention should be paid that setUpBeforeClass()
and tearDownAfterClass()
can only be declared as static functions.
Data Providers
Now, let’s move on to the main event of today. This feature is similar to the @testWith
that was introduced yesterday. Without further ado, let's take a look at an example!
- Example
<?php
namespace Tests\Unit;
use App\Services\TestService;
use Exception;
use PHPUnit\Framework\TestCase;
class TestServiceTest extends TestCase
{
/**
* @dataProvider bmiProvider
*/
public function testCanThrowException(float $height, float $weight)
{
$service = app(TestService::class);
$this->expectException(Exception::class);
$service->calculateBmi($height, $weight);
}
public function bmiProvider()
{
return [
[1.0, 0.0],
[0.0, 1.0],
[0.0, 0.0],
];
}
}
In the above code, we have created a Data Provider function, bmiProvider()
, and a test case function, testCanThrowException()
, and have marked it to use the bmiProvider()
Data Provider function. In this test class, testCanThrowException()
will actually be executed 3 times, respectively:
testCanThrowException(1.0, 0.0)
testCanThrowException(0.0, 1.0)
testCanThrowException(0.0, 0.0)
Actually, its usage is very similar to the @testWith
from the previous day, but it's more intuitive and more similar to writing test programs.
That concludes today’s introduction!
Next time, let’s take a look at Seeder.
If you liked this article or found it helpful, feel free to give it some claps and follow the author!