在 Validator 对象上模拟 fails() 和 make()
Mocking fails() and make() on a Validator object
我正在尝试使用 Mockery
模拟我从 Validator
对象获得的响应,我正在尝试最终强制通过或失败验证,以便我可以测试会发生什么验证后。我试过以下方法,但并不高兴。
$validator = Validator::shouldReceive('make')
->once()
->with([], $this->rules);
$validator->shouldReceive('fails')
->once()
->andReturn(true);
和
$validator = Validator::shouldReceive('make')
->once()
->with([], $this->rules)
->shouldReceive('fails')
->once()
->andReturn(true);
然后我将 class 中的验证器 属性 设置为从 Mockery
返回的对象
我要测试的函数看起来像这样
class JsonModel extends Model
{
private $validator;
public function createFromJSON(array $inputData, $throwException = false)
{
// This calls Validator::make
$this->makeValidator(
$inputData,
$this->getValidationRules() // An internal function that returns the rules for the Model
);
if($this->validator->fails()) {
if($throwException === true) {
throw new Exception('Validation failed');
} else {
return null;
}
}
return null;
/** @var Model $model */
$model = self::create($inputData);
return $model;
}
private function makeValidator($inputData, $ruleData)
{
$this->validator = Validator::make($inputData, $ruleData);
}
}
我对其他方法的建议持开放态度,我修复它不是必需的,因为我可以沿着 return 空路径,删除异常并假设 Validator 会完成它的工作,但这让我很烦.
所以我经过多次修补后找到了答案。这完全与您调用验证器的方式有关。我决定更改函数,以便它所做的只是使用规则集验证对象。所以我现在返回 passes()
而不是 fails()
的结果。对于任何其他试图嘲笑这个的人,下面的内容应该对你有所帮助。
public function testWithMockValidator()
{
// Mock the function you wish to mock and the result
$mockValidator = \Mockery::mock('\Illuminate\Validation\Validator');
$mockValidator->shouldReceive('passes')
->once()
->andReturn(false);
// Then Mock the factory that will be used to create the validator
$factory = '\Illuminate\Validation\Factory';
$mockFactory = \Mockery::mock($factory);
$mockFactory->shouldReceive('make')
->once()
->andReturn($mockValidator);
// Register the mock with the app
\App::instance($factory, $mockFactory);
// Create the object I need
$obj = \Mockery::mock(self::CLASS_NAME)->makePartial();
// Set a property using reflection
$property = UTH::i()->makePropertyAccessible(
self::CLASS_NAME,
self::PROP_VALIDATION_RULES
);
$property->setValue($obj, $this->rules);
// call my function (which has been renamed and redesigned to just validate the model
$return = $obj->validate(['foo' => true]);
// $return will be whatever you set it to in the mock above
$this->assertFalse($return);
}
这里是正在测试的class中的函数
public final function validate(array $inputData)
{
$factory = \App::make('\Illuminate\Validation\Factory');
// This retrieves the private property
$rules = $this->getValidationRules();
$this->validator = $factory->make($inputData, $rules);
return $this->validator->passes();
}
我正在尝试使用 Mockery
模拟我从 Validator
对象获得的响应,我正在尝试最终强制通过或失败验证,以便我可以测试会发生什么验证后。我试过以下方法,但并不高兴。
$validator = Validator::shouldReceive('make')
->once()
->with([], $this->rules);
$validator->shouldReceive('fails')
->once()
->andReturn(true);
和
$validator = Validator::shouldReceive('make')
->once()
->with([], $this->rules)
->shouldReceive('fails')
->once()
->andReturn(true);
然后我将 class 中的验证器 属性 设置为从 Mockery
返回的对象我要测试的函数看起来像这样
class JsonModel extends Model
{
private $validator;
public function createFromJSON(array $inputData, $throwException = false)
{
// This calls Validator::make
$this->makeValidator(
$inputData,
$this->getValidationRules() // An internal function that returns the rules for the Model
);
if($this->validator->fails()) {
if($throwException === true) {
throw new Exception('Validation failed');
} else {
return null;
}
}
return null;
/** @var Model $model */
$model = self::create($inputData);
return $model;
}
private function makeValidator($inputData, $ruleData)
{
$this->validator = Validator::make($inputData, $ruleData);
}
}
我对其他方法的建议持开放态度,我修复它不是必需的,因为我可以沿着 return 空路径,删除异常并假设 Validator 会完成它的工作,但这让我很烦.
所以我经过多次修补后找到了答案。这完全与您调用验证器的方式有关。我决定更改函数,以便它所做的只是使用规则集验证对象。所以我现在返回 passes()
而不是 fails()
的结果。对于任何其他试图嘲笑这个的人,下面的内容应该对你有所帮助。
public function testWithMockValidator()
{
// Mock the function you wish to mock and the result
$mockValidator = \Mockery::mock('\Illuminate\Validation\Validator');
$mockValidator->shouldReceive('passes')
->once()
->andReturn(false);
// Then Mock the factory that will be used to create the validator
$factory = '\Illuminate\Validation\Factory';
$mockFactory = \Mockery::mock($factory);
$mockFactory->shouldReceive('make')
->once()
->andReturn($mockValidator);
// Register the mock with the app
\App::instance($factory, $mockFactory);
// Create the object I need
$obj = \Mockery::mock(self::CLASS_NAME)->makePartial();
// Set a property using reflection
$property = UTH::i()->makePropertyAccessible(
self::CLASS_NAME,
self::PROP_VALIDATION_RULES
);
$property->setValue($obj, $this->rules);
// call my function (which has been renamed and redesigned to just validate the model
$return = $obj->validate(['foo' => true]);
// $return will be whatever you set it to in the mock above
$this->assertFalse($return);
}
这里是正在测试的class中的函数
public final function validate(array $inputData)
{
$factory = \App::make('\Illuminate\Validation\Factory');
// This retrieves the private property
$rules = $this->getValidationRules();
$this->validator = $factory->make($inputData, $rules);
return $this->validator->passes();
}