2016-06-09 6 views
0

ich kämpfen werde die query_builder Option in meinem Symfony Form Tests zu verspotten, ich habe versucht, die m:on(function() {}) verwenden, aber ohne Erfolg ...Mock Symfony Form ‚query_builder‘ mit Mockery

Hier ist ein Beispiel dessen, was ich bin versucht zu erreichen:

namespace AppBundle\Form; 

use Symfony\Component\Form\AbstractType; 

class MyCustomForm extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $userToken = 'this will be a TokenInterface object'; 

     $builder->add('field1', EntityType::class, [ 
      'label' => 'My Label', 
      'class' => 'AppBundle:MyClass', 
      'query_builder' => function (MyClassRepository $repository) use ($userToken) { 
       return $repository->setUserToken($userToken)->orderBy('alias.column_1'); 
     ]); 
    } 
} 

Was ich tun möchte, Test ist, dass die setUserToken und orderBy Methoden auf dem verspotteten Objekt aufgerufen werden.

namespace tests\Unit\AppBundle\Form; 

class MyCustomFormTest extends \PHPUnit_Framework_TestCase 
{ 
    // Setup test class etc... 

    public function testBuildingTheForm() 
    { 
     $this->builder->shouldReceive('add') 
      ->once() 
      ->with('field1', EntityType::class, [ 
       'label'   => 'My Label', 
       'class'   => 'AppBundle:MyClass', 
       'query_builder' => m::on(function ($closure) use ($userToken) { 
        // Test calls 
        // Test a mock method call with($userToken) 

        return true; 
       }, 
      ]); 

     $this->testClass->buildForm($this->builder, []); 
    } 
} 

Hier ist der Fehler Ich erhalte:

1) Tests\Unit\AppBundle\Form\MyCustomFormTest::testBuildingTheForm 
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_0_IteratorAggregate_Symfony_Component_Form_FormBuilderInterface::add("field1", "Symfony\Bridge\Doctrine\Form\Type\EntityType", array('label'=>'My Label','class'=>'AppBundle:MyClass','query_builder'=>'object(Closure)',)). Either the method was unexpected or its arguments matched no expected argument list for this method 

Antwort

0

Dank Dave Marshall, habe ich eine Lösung gefunden!

Testklasse:

namespace tests\Unit\AppBundle\Form; 

class MyCustomFormTest extends \PHPUnit_Framework_TestCase 
{ 
    // Setup test class etc... 

    public function testBuildingTheForm() 
    { 
     $this->builder->shouldReceive('add') 
      ->once() 
      ->with('field1', EntityType::class, m::on(function ($options) use ($userToken) { 
       $this->assertSame('My Label',   $options['label']); 
       $this->assertSame('AppBundle:MyClass', $options['class']); 

       $mockRepository = m::mock('AppBundle\Repository\ MyClassRepository'); 
       $mockRepository->shouldReceive('setUserToken')->with($userToken)->once()->andReturnSelf(); 
       $mockRepository->shouldReceive('orderBy')->with('alias.column_1', 'ASC')->once()->andReturnSelf(); 

       $options['query_builder']($mockRepository); 

       return true; 
      })); 

     $this->testClass->buildForm($this->builder, []); 
    } 
} 
2

Sie können nicht Mockery::on so einbetten, so dass Sie es bringen eine Ebene müssen, so etwas wie dieses:

public function testBuildingTheForm() 
{ 
    $this->builder->shouldReceive('add') 
     ->once() 
     ->with('field1', EntityType::class, m::on(function ($options) use ($userToken) { 
      $this->assertEquals('My Label', $options['label']; 
      $this->assertEquals('AppBundle:MyClass', $options['class']; 

      // whatever you need to test with $options['query_builder'] 

      return true; 
     })); 

    $this->testClass->buildForm($this->builder, []); 
}