用 Mockery 模拟 Symfony 表单 'query_builder'
Posted
技术标签:
【中文标题】用 Mockery 模拟 Symfony 表单 \'query_builder\'【英文标题】:Mock Symfony Form 'query_builder' with Mockery用 Mockery 模拟 Symfony 表单 'query_builder' 【发布时间】:2016-10-09 23:42:12 【问题描述】:我正在努力在 Symfony 表单测试中模拟 query_builder
选项,我尝试使用 m:on(function () )
但无济于事...
这是我想要实现的一个示例:
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');
]);
我想要做的是测试 setUserToken
和 orderBy
方法在模拟对象上被调用。
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, []);
这是我收到的错误:
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
【问题讨论】:
【参考方案1】:你不能像那样嵌入Mockery::on
,所以你需要把它提升一个级别,像这样:
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, []);
【讨论】:
【参考方案2】:感谢 Dave Marshall,我想出了一个解决方案!
测试类:
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, []);
【讨论】:
以上是关于用 Mockery 模拟 Symfony 表单 'query_builder'的主要内容,如果未能解决你的问题,请参考以下文章
用 Mockery 模拟 Laravel Model::increment()
PHP 单元测试 - 使用 Mockery 模拟静态自动加载类
使用 Mockery Eloquent 模型模拟 Laravel
使用 GitHub API Wrapper 在 Laravel 中进行模拟?