0

I develop new type, but I don't know how I can test it. Assert annotation is not load and validations is not called. Could any one please help me?

class BarcodeType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->
            add('price');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Bundles\MyBundle\Form\Model\Barcode',
            'intention'  => 'enable_barcode',
        ));
    }

    public function getName()
    {
        return 'enable_barcode';
    }
}

A have following model for storing form data.

namepspace Bundles\MyBundle\Form\Model;
class Barcode
{
    /**
     * @Assert\Range(
     *      min = "100",
     *      max = "100000",
     *      minMessage = "...",
     *      maxMessage = "..."
     * )
     */
    public $price;
}

I develop some test like this, the form didn't get valid data but it is valid! (Because annotation is not applied) I try adding ValidatorExtension but I dont know how can I set constructor paramaters

    function test...()
    {
        $field = $this->factory->createNamed('name', 'barcode');
        $field->bind(
                array(
                    'price'         => 'hello',
        ));

        $data = $field->getData(); 

        $this->assertTrue($field->isValid()); // Must not be valid 

    }
1
  • Documentation says : "Don't test the validation: it is applied by a listener that is not active in the test case and it relies on validation configuration. Instead, unit test your custom constraints directly." see symfony.com/doc/2.8/form/unit_testing.html Commented Jan 26, 2017 at 14:52

3 Answers 3

1

Not sure why you need to unit-test the form. Cant You unit test validation of Your entity and cover controller with your expected output? While testing validation of entity You could use something like this:

public function testIncorrectValuesOfUsernameWhileCallingValidation()
{
  $v =  \Symfony\Component\Validator\ValidatorFactory::buildDefault();
  $validator = $v->getValidator();

  $not_valid = array(
    'as', '1234567890_234567890_234567890_234567890_dadadwadwad231',
    "tab\t", "newline\n",
    "Iñtërnâtiônàlizætiøn hasn't happened to ", 'trśżź',
    'semicolon;', 'quote"', 'tick\'', 'backtick`', 'percent%', 'plus+', 'space ', 'mich @l'
  );    

  foreach ($not_valid as $key) {
    $violations = $validator->validatePropertyValue("\Brillante\SampleBundle\Entity\User", "username", $key);
    $this->assertGreaterThan(0, count($violations) ,"dissalow username to be ($key)");
  }

}

Sign up to request clarification or add additional context in comments.

1 Comment

I didn't know the technical solution for testing type like that, as mentioned it earlier, so I asked question. As you said, Must I generate controller and build this type in it, and then test the controller?
1

Functional test. Given that you generate a CRUD with app/console doctrine:generate:crud with routing=/ss/barcode, and given that maxMessage="Too high" you can:

class BarcodeControllerTest extends WebTestCase
{
    public function testValidator()
    {
        $client = static::createClient();
        $crawler = $client->request('GET', '/ss/barcode/new');
        $this->assertTrue(200 === $client->getResponse()->getStatusCode());
        // Fill in the form and submit it
        $form = $crawler->selectButton('Create')->form(array(
            'ss_bundle_eavbundle_barcodetype[price]'  => '12',
        ));

        $client->submit($form);
        $crawler = $client->followRedirect();
        // Check data in the show view
        $this->assertTrue($crawler->filter('td:contains("12")')->count() > 0);

        // Edit the entity
        $crawler = $client->click($crawler->selectLink('Edit')->link());
        /* force validator response: */ 
        $form = $crawler->selectButton('Edit')->form(array(
            'ss_bundle_eavbundle_barcodetype[price]'  => '1002',
        ));

        $crawler = $client->submit($form);
        // Check the element contains the maxMessage:
        $this->assertTrue($crawler->filter('ul li:contains("Too high")')->count() > 0);

    }
}

1 Comment

Thanks for your reply, @Albreto. But my data will not be saved in database, I will call service, then. I don't know, this is technical solution!? I think crawling the page, make test slower. what is you solution!?
-1

Include this line must be in Model and try it after include look like your model.

/* Include the required validators */
use Symfony\Component\Validator\Constraints as Assert;

namespace Bundles\MyBundle\Form\Model;
class Barcode
{
    /**
     * @Assert\Range(
     *      min = "100",
     *      max = "100000",
     *      minMessage = "min message here",
     *      maxMessage = "max message here"
     * )
     */
    public $price;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.