我有一个测试服,用于在命名空间中创建AppCommands
CLI 程序。我遇到的问题是,似乎 laravel 容器无法解决测试方法依赖项或 laravel 助手,... .我使用的是 Windows 10。
PHP代码:
<?php
use IlluminateFoundationTestingWithoutMiddleware;
use IlluminateFoundationTestingDatabaseMigrations;
use IlluminateFoundationTestingDatabaseTransactions;
use ACMESomeClass;
class CLICommandTest extends TestCase
{
use DatabaseTransactions;
protected $key = '';
protected $someClass = null;
public function __construct(SomeClass $someClass)
{
parent::__construct();
$this->someClass = $someClass;
$this->key = config('someconfig')['key'];
}
/*
* test handle method
*/
public function testHandle()
{
//assertions
}
}
我已经为此创建并包含服务提供商:
<?php
use ACMESomeClass;
$this->app->bind('ACMESomeClass', function($app){
return new SomeClass($value);
});
当我从PATH
或vendor/bin
运行phpunit
时,会出现此错误:
PHP Fatal error: Uncaught TypeError: Argument 1 passed to CLICommandTest::__construct() must be an instance of ACMESomeClass, none given, called in phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php on line 475 and defined in C:pathtestsCLICommandTest.php:16
Stack trace:
#0 phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php(475): CLICommandTest->__construct()
#1 phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php(880): PHPUnit_Framework_TestSuite::createTest(Object(ReflectionClass), 'testHandle')
#2 phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php(195): PHPUnit_Framework_TestSuite->addTestMethod(Object(ReflectionClass), Object(ReflectionMethod))
#3 phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php(297): PHPUnit_Framework_TestSuite->__construct(Object(ReflectionClass))
#4 phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php(381): PHPUnit_Framework_TestSuite->addTestSuite(Object(ReflectionClass))
#5 phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuit in C:pathtestsCLICommandTest.php on line 16
Fatal error: Uncaught TypeError: Argument 1 passed to CLICommandTest::__construct() must be an instance of ACMESomeClass, none given, called in phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php on line 475 and defined in C:pathtestsCLICommandTest.php on line 16
TypeError: Argument 1 passed to CLICommandTest::__construct() must be an instance of ACMESomeClass, none given, called in phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php on line 475 in C:pathtestsCLICommandTest.php on line 16
Call Stack:
0.0036 492584 1. {main}() C:PHPUnitphpunit:0
0.1375 8875000 2. PHPUnit_TextUI_Command::main() C:PHPUnitphpunit:515
0.1375 8878160 3. PHPUnit_TextUI_Command->run() phar://C:/PHPUnit/phpunit/phpunit/TextUI/Command.php:106
0.1375 8878160 4. PHPUnit_TextUI_Command->handleArguments() phar://C:/PHPUnit/phpunit/phpunit/TextUI/Command.php:117
0.1624 10379328 5. PHPUnit_Util_Configuration->getTestSuiteConfiguration() phar://C:/PHPUnit/phpunit/phpunit/TextUI/Command.php:663
0.1624 10379912 6. PHPUnit_Util_Configuration->getTestSuite() phar://C:/PHPUnit/phpunit/phpunit/Util/Configuration.php:796
0.1651 10381496 7. PHPUnit_Framework_TestSuite->addTestFiles() phar://C:/PHPUnit/phpunit/phpunit/Util/Configuration.php:885
0.1651 10381496 8. PHPUnit_Framework_TestSuite->addTestFile() phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php:409
0.1732 10916648 9. PHPUnit_Framework_TestSuite->addTestSuite() phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php:381
0.1732 10917104 10. PHPUnit_Framework_TestSuite->__construct() phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php:297
0.1733 10982344 11. PHPUnit_Framework_TestSuite->addTestMethod() phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php:195
0.1733 10982760 12. PHPUnit_Framework_TestSuite::createTest() phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php:880
0.1735 10986272 13. CLICommandTest->__construct() phar://C:/PHPUnit/phpunit/phpunit/Framework/TestSuite.php:475
问题出在哪里?
在use
中,类的块名应匹配:
<?php
use ACMESomeClass; // <== see, it should be SomeClass here, not someClass
$this->app->bind('ACMESomeClass', function($app){
return new SomeClass($value);
});
除此之外,您的class CLICommandTest extends TestCase
实际上扩展了\PHPUnit_Framework_TestCase。它的构造函数签名是:
public function __construct($name = null, array $data = [], $dataName = '')
其中第一个参数是测试的名称,它是可选的。你
public function __construct(SomeClass $someClass)
用更严格的要求覆盖签名:第一个参数是必需的,并且必须具有类型 SomeClass
。它会制动合约,因此测试运行程序无法实例化测试用例。
我建议阅读Laravel测试和PHPUnit文档,了解如何编写测试以及为什么很少需要扩展构造函数。
看起来你也想使用设置/拆卸方法:
class CLICommandTest extends TestCase
{
use DatabaseTransactions; // <== please double check you need the trait here
protected $key = '';
protected $someClass = null;
public function setUp()
{
// here you probably want to create an instance of your application
$this->someClass = new SomeClass;
$this->key = 'value of the key';
}
...
Laravel和phpunit是独立的框架。只有在 laravel 应用程序的某些部分(控制器、事件等)中,您才能传入类依赖项,服务容器将解析它们。phpunit与此无关。
尽管您仍然可以使用帮助程序函数来利用容器:
$someObject = app()->make(SomeClass::class);
但是,对于测试,您可能希望模拟对象而不是从头开始构建它,在这种情况下,请使用 Mockery 库。