在Validator对象上模拟失败()和make()

时间:2015-07-24 14:31:44

标签: php laravel phpunit laravel-5 mockery

我正在尝试使用Validator模拟我从Mockery对象获得的响应,我最终尝试强制验证通过或失败,以便我可以测试在验证。我没有高兴地试过以下。

$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);    

使用这两个我然后将类中的validator属性设置为从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);
    }
}

我愿意接受其他方法的建议,这不是解决问题的必要条件,因为我可以直接返回null路径,删除异常并假设Validator会完成它的工作,但这会让我烦恼。

1 个答案:

答案 0 :(得分:1)

所以我经过多次修补后找到了答案。这与您调用验证器的方式有关。我决定更改函数,以便它所做的就是使用规则集验证对象。所以我现在返回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);
}

这是被测试类中的函数

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();
}