I want to test that I convert form data correctly, and so I wrote a unit test based on how the Symfony 3.4 docs instruct me to. It is even marked as the basics, so I did not expect any issues, but I do!
When running the following test I get ArgumentCountError : Too few arguments to function Symfony\Bridge\Doctrine\Form\Type\DoctrineType::__construct(), 0 passed in /Users/.../vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php on line 92 and exactly 1 expected
. I see this is more or less what this guy got, but I could not make sense of it.
<?php
namespace Tests\MyProject\BackendBundle;
use MyProject\BackendBundle\Entity\ExerciseInfo;
use MyProject\BackendBundle\Form\ApiExerciseInfoType;
use Symfony\Component\Form\Test\TypeTestCase;
class FormBuilderOfExerciseInfoTest extends TypeTestCase
{
public function test_something()
{
$requestEntry = array(
'score_cols' =>
array(
0 => 'REPS',
1 => 'PAUSE',
2 => 'KG_WEIGHTS',
),
'id' => 'C4F1D2A3-762D-4548-B0E3-C0B3912FC02C',
'score_vals' =>
array(
0 =>
array(
'type' => 'REPS',
'value' =>
array(
0 => 12,
1 => 12,
2 => 12,
),
),
1 =>
array(
'type' => 'PAUSE',
'value' =>
array(
0 => 10,
1 => 10,
2 => 10,
),
),
2 =>
array(
'type' => 'KG_WEIGHTS',
'value' =>
array(
0 => 0,
1 => 0,
2 => 0,
),
),
),
'score_count' => 3,
'exercise_id' => 'b9c90921-a594-4c2c-b9df-071357fd5247',
'notes_sets' =>
array(
0 => '',
1 => '',
2 => '',
),
'result_vals' =>
array(),
'exercise_notes' => '',
'score_type' => 'REPS',
);
$model = new ExerciseInfo();
$form = $this->factory->create(ApiExerciseInfoType::class, $model);
$form->submit($requestEntry);
/**
* @var $data ExerciseInfo
*/
$data = $form->getData();
$exerciseSuperSet = $data->getScoreCols();
self::assertFalse(empty($exerciseSuperSet));
}
}
Form type
class ApiExerciseInfoType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', HiddenType::class)
->add('exercise_id', EntityType::class, [
'class' => 'PETE\BackendBundle\Entity\Exercise',
'property_path' => 'exercise',
])
->add('notes_sets', null, [])
->add('exercise_notes', null, [])
->add('score_cols', TextType::class, [
'property_path' => 'scoreCols'
])
->add('score_type', TextType::class, [
'property_path' => 'scoreType'
])
->add('score_count', null, [
'property_path' => 'scoreCount',
])
->add('score_vals', null, [
'property_path' => 'scoreVals',
])
->add('result_vals', null, [
'property_path' => 'resultVals',
])
;
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'PETE\BackendBundle\Entity\ExerciseInfo',
'csrf_protection' => false,
'allow_extra_fields' => true,
));
}
public function getBlockPrefix()
{
return '';
}
}
I will list up what I actually did, which is turn this into a kind of integration test, using the container, by extending KernelTestCase
instead of TypeTestCase
and asking the container for the form factory. Hopefully there is a better way.
class FormBuilderOfExerciseInfoTest extends KernelTestCase
{
public function test_something()
{
$kernel = self::bootKernel();
/**
* @var $container ContainerInterface
*/
$container = $kernel->getContainer();
$requestEntry = array(
'score_cols' =>
array(
0 => 'REPS',
1 => 'PAUSE',
2 => 'KG_WEIGHTS',
),
...
$model = new ExerciseInfo();
$formFactory = $container->get("form.factory");
$form = $formFactory->create(ApiExerciseInfoType::class, $model);
...