我正在尝试编写一个测试来检查用户是否在表单有效时被重定向。为了做到这一点,我模拟了我的表单并让它在调用 isValid 时返回 true。
我收到以下错误:
/home/razvbir/PhpstormProjects/expenses.money/module/User/test/Controller/RegisterControllerTest.php:94
foreach() 参数必须是 array|object 类型,给定为 null /home/razvbir/PhpstormProjects/expenses.money/vendor/laminas/laminas-form/src/Fieldset.php:357
foreach() 参数必须是 array|object 类型,给定为 null /home/razvbir/PhpstormProjects/expenses.money/vendor/laminas/laminas-form/src/Fieldset.php:302
/home/razvbir/PhpstormProjects/expenses.money/module/User/test/Controller/RegisterControllerTest.php:122
这是我的测试代码:
<?php
declare(strict_types=1);
namespace UserTest\Controller;
use Laminas\Form\FormElementManager;
use Laminas\Http\Request;
use Laminas\ServiceManager\ServiceManager;
use Laminas\Stdlib\ArrayUtils;
use Laminas\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
use Mockery\Adapter\Phpunit\MockeryTestCaseSetUp;
use User\Form\RegisterForm;
class RegisterControllerTest extends AbstractHttpControllerTestCase
{
use MockeryPHPUnitIntegration;
use MockeryTestCaseSetUp;
protected $traceError = true;
protected Mockery\MockInterface $registerForm;
protected Mockery\MockInterface $formElementManager;
protected function mockeryTestSetUp() {}
protected function mockeryTestTearDown() {}
protected function configureServiceManager(ServiceManager $serviceManager): void
{
$serviceManager->setAllowOverride(true);
$serviceManager->setService('config', $this->overrideConfig($serviceManager->get('config')));
$serviceManager->setService(FormElementManager::class, $this->formElementManager);
$serviceManager->setAllowOverride(false);
}
protected function overrideConfig(array $config): array
{
$testConfigOverrides = include __DIR__ . '/../../../../config/test.config.php';
return ArrayUtils::merge($config, $testConfigOverrides);
}
protected function mockRegisterForm(): void
{
$this->registerForm = Mockery::mock(RegisterForm::class)->makePartial();
$this->registerForm
->shouldReceive('isValid')
->andReturnTrue();
$this->registerForm
->shouldReceive('getData')
->andReturn([
'email' => '[email protected]',
'password' => 'parolameasuperba1'
]);
}
protected function mockFormElementManager(): void
{
$this->formElementManager = Mockery::mock(FormElementManager::class);
$this->formElementManager
->makePartial()
->shouldReceive('get')
->with(RegisterForm::class)
->andReturn($this->registerForm);
}
protected function setUp(): void
{
$applicationConfigOverrides = [];
$this->setApplicationConfig(ArrayUtils::merge(
include __DIR__ . '/../../../../config/application.config.php',
$applicationConfigOverrides
));
parent::setUp();
$this->mockRegisterForm();
$this->mockFormElementManager();
$this->configureServiceManager($this->getApplicationServiceLocator());
}
public function tearDown(): void
{
Mockery::close();
}
public function testRegisterPageCanBeAccessed()
{
$this->dispatch('/user/register');
$this->assertResponseStatusCode(200);
$this->assertModuleName('user');
$this->assertControllerName('User\Controller\RegisterController');
$this->assertControllerClass('RegisterController');
$this->assertMatchedRouteName('user/register/expose');
$this->assertQuery('form#registerForm[method="POST"]');
$this->assertQuery('form#registerForm label[for="email"]');
$this->assertQuery('form#registerForm input[name="email"]');
$this->assertQuery('form#registerForm label[for="password"]');
$this->assertQuery('form#registerForm input[name="password"]');
$this->assertQuery('form#registerForm label[for="confirm-password"]');
$this->assertQuery('form#registerForm input[name="confirm-password"]');
$this->assertQuery('form#registerForm input[type="submit"]');
}
/**
* @group optional
*/
public function testRegisterPageRedirectsAfterCreatingNewUser()
{
$this->registerForm
->shouldReceive('isValid')
->once()
->andReturnTrue();
$this->dispatch('/user/register', Request::METHOD_POST);
$this->assertResponseStatusCode(303);
$this->assertRedirect();
}
}
这里是控制器:
<?php
declare(strict_types=1);
namespace User\Controller;
use Laminas\Form\Form;
use Laminas\Mvc\Controller\AbstractActionController;
use User\Model\UserCommandInterface;
use User\Model\User;
class RegisterController extends AbstractActionController
{
public function __construct(
protected Form $form,
protected UserCommandInterface $command
) {}
public function exposeRegisterAction(): array
{
return [
'form' => $this->form
];
}
public function processRegisterAction(): array
{
$this->form->setData($this->getRequest()->getPost());
if ($this->form->isValid()) {
$filteredData = $this->form->getData();
$newUser = new User(email: $filteredData['email']);
$newUser->setHashFromPlainText($filteredData['password']);
$this->command->insertUser($newUser);
$this->redirect()->toRoute('home');
}
return [
'form' => $this->form
];
}
}