Home > Software engineering >  How to retrieve form constraint violations messages with profiler in Symfony 6 unit test
How to retrieve form constraint violations messages with profiler in Symfony 6 unit test

Time:09-23

I'm trying to unit tests some potential behaviors on a contact form in Symfony 6, and specifically test the messages returned by the constraints on the form fields.

To do so I try to get these messages within the profiler, but I can't find any method to retrieve the error messages returned, all I found is how to get the number of errors :

 public function testFailureEmailSending()
{
    // Given
    $this->client->enableProfiler();

    // When
    $this->client->request('POST', '/contact', [
        'contact' => [
            'name' => '',
            'email' => '',
            'phone' => '',
            'message' => 'Less than 30 characters !',
        ]]);

    if ($profile = $this->client->getProfile()) {
        $validator = $profile->getCollector('validator');
        $violationsCount = $validator->getViolationsCount();
        // how to retrieve error messages ?
    }

    // Then
    $this->assertEquals(4, $violationsCount); // works
}

CodePudding user response:

It is a bit hard to get to the constraint violations via the profiler. You might want to write a proper unit test just for the validation, without the whole request-controller-overhead. Symfony provides a ValidatorBuilder, you can use in a unit test quite easily:

public function testFailureEmailSending(): void
{
    $validator = Validation::createValidationBuilder()
        ->enableAnnotationMapping()
        ->getValidator();

    $violations = $validator->validate($contact);

    // Perform assertions
}

That being said, the collector provides a method getCalls() which returns the collected data from the validator. The TraceableValidator used by the DataCollector will add the collected data whenever validate is called, as you can see in TraceableValidator.php#L97-101.

In other words, you should be able to retrieve the violations by doing:

// Be careful, this is not the actual array, but a Data-object from the VarDumper component, but it provides array access
$collectedData = $profile->getCollector('validator')->getCalls();
// You might need to call iterator_to_array() first for the next line to work
$violations = end($collectedData)['violations'];
  • Related