Phpunit中上上篇我们了解了withConsecutive支持多次调用某个方法时的参数断言,已经是能够满足绝大多数情况了。
那么接下来这个更让人大开眼界,callback断言利用匿名方法自定义断言,该匿名方法返回为true即为断言为真。
了解下面这个案例之前建议先了解下https://www.gaojiupan.cn/manshenghuo/chengxurensheng/4048.html
那么我们的具体的实例:
SubjectTest.php:
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class SubjectTest extends TestCase
{
public function testErrorReported(): void
{
// 为 Observer 类建立仿件,模仿 reportError() 方法
$observer = $this->createMock(Observer::class);
//断言reportError方法被执行一次
//断言reportError方法第一个接收参数是大于0的
//断言reportError方法第二个接收参数包含字符串'Something'
$observer->expects($this->once())
->method('reportError')
->with(
$this->greaterThan(0),
$this->stringContains('Something'),
$this->callback(function($subject)
{
return is_callable([$subject, 'getName']) && $subject->getName() == 'My subject1';
}
));
$subject = new Subject('My subject');
$subject->attach($observer);
// doSomethingBad() 方法应当会通过
// reportError() 方法向 observer 报告错误。
$subject->doSomethingBad();
}
}
这里运行肯定是会出现问题的,因为我new的是My subject而断言的是My subject1:
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\SubjectTest.php
PHPUnit 9.5.8 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 00:00.009, Memory: 22.00 MB
There was 1 failure:
1) SubjectTest::testErrorReported
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.0147 1571792 1. {main}() D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:0
0.1354 18893800 2. PHPUnit\TextUI\Command::main(???) D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:2249
0.1354 18893912 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.1403 19071384 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.1738 19916264 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.1740 19916288 6. PHPUnit\TextUI\DefaultResultPrinter->printFailures(class PHPUnit\Framework\TestResult) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:154
0.1740 19916288 7. PHPUnit\TextUI\DefaultResultPrinter->printDefects(array(1), string(7)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:299
0.1744 19916288 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.1749 19916288 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.1749 19916288 10. PHPUnit\Framework\ExpectationFailedException->__toString() phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:288
0.1749 19924480 11. PHPUnit\Util\Filter::getFilteredStacktrace(class PHPUnit\Framework\ExpectationFailedException) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Framework/Exception/Exception.php:58
0.1750 19925616 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.1750 19925760 13. PHPUnit\Util\Filter::fileIsExcluded(string(109), class PHPUnit\Util\ExcludeList) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:76
0.1750 19925760 14. PHPUnit\Util\ExcludeList->isExcluded(string(109)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:80
0.1750 19925760 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.1750 19925760 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.1750 19925824 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.1750 19925888 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.0147 1571792 1. {main}() D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:0
0.1354 18893800 2. PHPUnit\TextUI\Command::main(???) D:\phpstudy_pro\Extensions\php\php7.3.4nts\phpunit-9.5.8.phar:2249
0.1354 18893912 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.1403 19071384 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.1738 19916264 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.1740 19916288 6. PHPUnit\TextUI\DefaultResultPrinter->printFailures(class PHPUnit\Framework\TestResult) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:154
0.1740 19916288 7. PHPUnit\TextUI\DefaultResultPrinter->printDefects(array(1), string(7)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:299
0.1744 19916288 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.1749 19916288 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.1749 19916288 10. PHPUnit\Framework\ExpectationFailedException->__toString() phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/TextUI/DefaultResultPrinter.php:288
0.1749 19924480 11. PHPUnit\Util\Filter::getFilteredStacktrace(class PHPUnit\Framework\ExpectationFailedException) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Framework/Exception/Exception.php:58
0.1750 19925616 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.1750 19925760 13. PHPUnit\Util\Filter::fileIsExcluded(string(109), class PHPUnit\Util\ExcludeList) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:76
0.1750 19925760 14. PHPUnit\Util\ExcludeList->isExcluded(string(109)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/Filter.php:80
0.1750 19925760 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.1750 19925760 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.1750 19925824 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.1750 19925888 18. autoload(string(37)) phar://D:/phpstudy_pro/Extensions/php/php7.3.4nts/phpunit-9.5.8.phar/phpunit/Util/ExcludeList.php:182
Expectation failed for method name is "reportError" when invoked 1 time(s)
Parameter 2 for invocation Observer::reportError(23, 'Something bad happened', Subject Object (...)) does not match expected value.
Failed asserting that Subject Object &0000000005528418000000004160e70a (
'observers' => Array &0 (
0 => Mock_Observer_388948e6 Object &0000000005528414000000004160e70a (
'__phpunit_originalObject' => null
'__phpunit_returnValueGeneration' => true
'__phpunit_invocationMocker' => PHPUnit\Framework\MockObject\InvocationHandler Object &000000000552841b000000004160e70a (
'matchers' => Array &1 (
0 => PHPUnit\Framework\MockObject\Matcher Object &0000000005528413000000004160e70a (
'invocationRule' => PHPUnit\Framework\MockObject\Rule\InvokedCount Object &000000000552841c000000004160e70a (
'expectedCount' => 1
'invocations' => Array &2 (
0 => PHPUnit\Framework\MockObject\Invocation Object &0000000005528468000000004160e70a (
'className' => 'Observer'
'methodName' => 'reportError'
'parameters' => Array &3 (
0 => 23
1 => 'Something bad happened'
2 => Subject Object &0000000005528418000000004160e70a
)
'returnType' => ''
'isReturnTypeNullable' => false
'proxiedCall' => false
'object' => Mock_Observer_388948e6 Object &0000000005528414000000004160e70a
)
)
)
'afterMatchBuilderId' => null
'afterMatchBuilderIsInvoked' => false
'methodNameRule' => PHPUnit\Framework\MockObject\Rule\MethodName Object &000000000552846e000000004160e70a (
'constraint' => PHPUnit\Framework\MockObject\MethodNameConstraint Object &0000000005528411000000004160e70a (
'methodName' => 'reportError'
'exporter' => null
)
)
'parametersRule' => PHPUnit\Framework\MockObject\Rule\Parameters Object &0000000005528469000000004160e70a (
'parameters' => Array &4 (
0 => PHPUnit\Framework\Constraint\GreaterThan Object &000000000552846d000000004160e70a (
'value' => 0
'exporter' => null
)
1 => PHPUnit\Framework\Constraint\StringContains Object &000000000552846c000000004160e70a (
'string' => 'Something'
'ignoreCase' => true
'exporter' => null
)
2 => PHPUnit\Framework\Constraint\Callback Object &000000000552846a000000004160e70a (
'callback' => Closure Object &000000000552846b000000004160e70a (
0 => Closure Object &000000000552846b000000004160e70a
)
'exporter' => PHPUnit\SebastianBergmann\Exporter\Exporter Object &0000000005528467000000004160e70a ()
)
)
'invocation' => PHPUnit\Framework\MockObject\Invocation Object &0000000005528468000000004160e70a
'parameterVerificationResult' => null
)
'stub' => null
)
)
'matcherMap' => Array &5 ()
'configurableMethods' => Array &6 (
0 => PHPUnit\Framework\MockObject\ConfigurableMethod Object &0000000005528417000000004160e70a (
'name' => 'update'
'returnType' => PHPUnit\SebastianBergmann\Type\UnknownType Object &0000000005528412000000004160e70a ()
)
1 => PHPUnit\Framework\MockObject\ConfigurableMethod Object &0000000005528416000000004160e70a (
'name' => 'reportError'
'returnType' => PHPUnit\SebastianBergmann\Type\UnknownType Object &000000000552846f000000004160e70a ()
)
)
'returnValueGeneration' => true
'deferredError' => null
)
)
)
'name' => 'My subject'
) is accepted by specified callback.
C:\Users\Administrator\PhpstormProjects\untitled\organizing\src\Subject.php:35
C:\Users\Administrator\PhpstormProjects\untitled\organizing\tests\SubjectTest.php:29
FAILURES!
Tests: 1, Assertions: 0, Failures: 1.
所以说接下来将SubjectTest.php修改如:
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class SubjectTest extends TestCase
{
public function testErrorReported(): void
{
// 为 Observer 类建立仿件,模仿 reportError() 方法
$observer = $this->createMock(Observer::class);
//断言reportError方法被执行一次
//断言reportError方法第一个接收参数是大于0的
//断言reportError方法第二个接收参数包含字符串'Something'
$observer->expects($this->once())
->method('reportError')
->with(
$this->greaterThan(0),
$this->stringContains('Something'),
$this->callback(function($subject)
{
return is_callable([$subject, 'getName']) && $subject->getName() == 'My subject';
}
));
$subject = new Subject('My subject');
$subject->attach($observer);
// doSomethingBad() 方法应当会通过
// reportError() 方法向 observer 报告错误。
$subject->doSomethingBad();
}
}
那么再次运行就没有问题了:
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\SubjectTest.php
PHPUnit 9.5.8 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 00:00.004, Memory: 22.00 MB
OK (1 test, 1 assertion)