<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class DatabaseTest extends TestCase
{
public function testStub(): void
{
// 为 SomeClass 类创建桩件。
$stub = $this->createStub(Database::class);
// 配置桩件。
$stub->method('doSomething')
->willReturn('foo');
// 现在调用 $stub->doSomething() 会返回 'foo'。
$this->assertSame('foo', $stub->doSomething());
}
}
此时运行是会报错的
C:\Users\Administrator\PhpstormProjects\untitled\organizing>D:\phpstudy_pro\Extensions\php\php7.3.4nts\php.exe D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar C:\Users\Administrator\PhpstormProjects\untitled\organizing\tests\DatabaseTest.php
PHPUnit 9.5.8 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 00:00.005, Memory: 20.00 MB
There was 1 error:
1) DatabaseTest::testStub
Warning: include(PHPUnit\Composer\Autoload\ClassLoader.php): failed to open stream: No such file or directory in C:\Users\Administrator\PhpstormProjects\untitled\organizing\src\autoload.php on line 3
Call Stack:
0.0164 1571536 1. {main}() D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:0
0.1511 18893544 2. PHPUnit\TextUI\Command::main(???) D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:2249
0.1511 18893656 3. PHPUnit\TextUI\Command->run(array(2), true) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/Command.php:93
0.1561 19068064 4. PHPUnit\TextUI\TestRunner->run(class PHPUnit\Framework\TestSuite, array(15), array(0), true) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/Command.php:124
0.1914 19109944 5. PHPUnit\TextUI\DefaultResultPrinter->printResult(class PHPUnit\Framework\TestResult) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/TestRunner.php:496
0.1918 19109968 6. PHPUnit\TextUI\DefaultResultPrinter->printErrors(class PHPUnit\Framework\TestResult) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:152
0.1918 19109968 7. PHPUnit\TextUI\DefaultResultPrinter->printDefects(array(1), string(5)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:295
0.1953 19109968 8. PHPUnit\TextUI\DefaultResultPrinter->printDefect(class PHPUnit\Framework\TestFailure, long) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:272
0.1958 19109968 9. PHPUnit\TextUI\DefaultResultPrinter->printDefectTrace(class PHPUnit\Framework\TestFailure) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:279
0.1958 19109968 10. PHPUnit\Framework\MockObject\ClassIsFinalException->__toString() phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:288
0.1958 19110128 11. PHPUnit\Util\Filter::getFilteredStacktrace(class PHPUnit\Framework\MockObject\ClassIsFinalException) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Framework/Exception/Exception.php:58
0.1958 19111264 12. PHPUnit\Util\Filter::shouldPrintFrame(array(2), string(25), class PHPUnit\Util\ExcludeList) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:57
0.1958 19111408 13. PHPUnit\Util\Filter::fileIsExcluded(string(111), class PHPUnit\Util\ExcludeList) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:76
0.1958 19111408 14. PHPUnit\Util\ExcludeList->isExcluded(string(111)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:80
0.1958 19111408 15. PHPUnit\Util\ExcludeList->initialize() phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:166
0.1959 19111408 16. class_exists(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
0.1959 19111472 17. spl_autoload_call(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
0.1959 19111536 18. autoload(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
Warning: include(): Failed opening 'PHPUnit\Composer\Autoload\ClassLoader.php' for inclusion (include_path='.;C:\php\pear') in C:\Users\Administrator\PhpstormProjects\untitled\organizing\src\autoload.php on line 3
Call Stack:
0.0164 1571536 1. {main}() D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:0
0.1511 18893544 2. PHPUnit\TextUI\Command::main(???) D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:2249
0.1511 18893656 3. PHPUnit\TextUI\Command->run(array(2), true) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/Command.php:93
0.1561 19068064 4. PHPUnit\TextUI\TestRunner->run(class PHPUnit\Framework\TestSuite, array(15), array(0), true) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/Command.php:124
0.1914 19109944 5. PHPUnit\TextUI\DefaultResultPrinter->printResult(class PHPUnit\Framework\TestResult) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/TestRunner.php:496
0.1918 19109968 6. PHPUnit\TextUI\DefaultResultPrinter->printErrors(class PHPUnit\Framework\TestResult) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:152
0.1918 19109968 7. PHPUnit\TextUI\DefaultResultPrinter->printDefects(array(1), string(5)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:295
0.1953 19109968 8. PHPUnit\TextUI\DefaultResultPrinter->printDefect(class PHPUnit\Framework\TestFailure, long) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:272
0.1958 19109968 9. PHPUnit\TextUI\DefaultResultPrinter->printDefectTrace(class PHPUnit\Framework\TestFailure) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:279
0.1958 19109968 10. PHPUnit\Framework\MockObject\ClassIsFinalException->__toString() phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:288
0.1958 19110128 11. PHPUnit\Util\Filter::getFilteredStacktrace(class PHPUnit\Framework\MockObject\ClassIsFinalException) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Framework/Exception/Exception.php:58
0.1958 19111264 12. PHPUnit\Util\Filter::shouldPrintFrame(array(2), string(25), class PHPUnit\Util\ExcludeList) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:57
0.1958 19111408 13. PHPUnit\Util\Filter::fileIsExcluded(string(111), class PHPUnit\Util\ExcludeList) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:76
0.1958 19111408 14. PHPUnit\Util\ExcludeList->isExcluded(string(111)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:80
0.1958 19111408 15. PHPUnit\Util\ExcludeList->initialize() phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:166
0.1959 19111408 16. class_exists(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
0.1959 19111472 17. spl_autoload_call(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
0.1959 19111536 18. autoload(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
PHPUnit\Framework\MockObject\ClassIsFinalException: Class "Database" is declared "final" and cannot be mocked
C:\Users\Administrator\PhpstormProjects\untitled\organizing\tests\DatabaseTest.php:9
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
因为被上桩的类不能用final修饰
所以修改成如:
Database.php:
<?php declare(strict_types=1);
class Database
{
public function doSomething()
{
// 随便做点什么。
}
}
然后再次运行
C:\Users\Administrator\PhpstormProjects\untitled\organizing>D:\phpstudy_pro\Extensions\php\php7.3.4nts\php.exe D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar C:\Users\Administrator\PhpstormProjects\untitled\organizing\tests\DatabaseTest.php
PHPUnit 9.5.8 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.004, Memory: 20.00 MB
OK (1 test, 1 assertion)
这样就ok了。
接下来我们来了解下什么是桩件:
stub(桩件):
“将对象替换为(可选地)返回配置好的返回值的测试替身的实践方法称为上桩(stubbing)”——这是官方文档给出的上桩解释
也许这个形容有点抽象来着,大概的表达了这么个意思:比如说你有一个方法,依赖了数据库查询,当数据库一切正常时,这个单元测试是OK的,但是当数据库挂掉的时候,这个单测就会挂掉。这就不符合咱们
单测的一些意义了,单测应该是纯净的,只验证你的逻辑这些,所以呢,我们就需要把这些mock掉,怎么mock呢?就是你可以自定义一个数据库的返回,比如刚才说的我需要数据库的某个字段返回1的时候,单测就能成功,
这时候我们不能完全依赖数据库,万一被别人改了怎么办?我就自己定义这个字段返回1;以后就算网络不通,这个字段在这里都会返回1,是一个定义死了数据,这样就等于把数据库查询给mock了
那么上面$stub->method('doSomething') ->willReturn('foo');的意思就是说相当于我这里解释的,写个死值,这里假定数据库正常情况下doSomething方法应该返回的值是foo。