【问题标题】:Test the exist validator in Yii2 without database with mockeryBuilder()使用 mockeryBuilder() 在没有数据库的情况下测试 Yii2 中的存在验证器
【发布时间】:2018-04-09 23:53:28
【问题描述】:

我想在 Yii 2 中测试我的 AR 模型而不连接到数据库,所以我使用 mockBuilder() 但我不知道如何将模拟对象传递给模型存在验证器,例如:

class Comment extends ActiveRecord
{
  public function rules()
  {
    return [
      [['id', 'user_id', 'post_id'], 'comment'],
      ['comment', 'string',
        'max' => 200
      ],
      ['user_id', 'exist',
        'targetClass'     => User::className(),
        'targetAttribute' => 'id'
      ],
      ['post_id', 'exist',
        'targetClass'     => Post::className(),
        'targetAttribute' => 'id'
      ]
    ];
  }
}

class CommentTest extends TestCase
{
  public function testValidateCorrectData()
  {
    $user = $this->getMockBuilder(User::className())
      ->setMethods(['find'])
      ->getMock();

    $user->method('find')->willReturn(new User([
      'id' => 1
    ]));

    $post = $this->getMockBuilder(Post::className())
      ->setMethods(['find'])
      ->getMock();

    $post->method('find')->willReturn(new Post([
      'id' => 1
    ]));

    // How can I pass to $user and $post to exist validator in Comment model?

    $comment = new Comment([
      'user_id' => 1,
      'post_id' => 1,
      'comment' => 'test...'
    ]);

    expect_that($comment->validate());
  }
}

好的,这不是最好的代码,只是我想介绍一下我想做的事情。

【问题讨论】:

    标签: activerecord yii2 phpunit codeception mockery


    【解决方案1】:

    Yii2 ExistValidator 使用 ActiveQuery::exists() 来检查是否存在,您应该将生成的验证器替换为模拟对象,其中 createQuery 方法返回 ActiveQuery 的模拟对象,其中 ::exists() 返回您想要的东西(真/假),例如

    $activeQueryMock = $this->getMockBuilder(ActiveQuery::className())
        ->disableOriginalConstructor()
        ->setMethods(['exists'])
        ->getMock();
    
    $activeQueryMock->expects($this->any())
        ->method('exists')
        ->willReturn($value); //Your value here true/false
    
    $model = $this->getMockBuilder(Comment::className())
        ->setMethods(['getActiveValidators'])
        ->getMock();
    
    $model->expects($this->any())
        ->method('getActiveValidators')
        ->willReturnCallback(function () use ($activeQueryMock) {
            $validators = (new Comment())->activeValidators;
            foreach ($validators as $key => $validator) {
                if (($validator instanceof ExistValidator) && ($validator->attributes = ['user_id'])) {
    
                    $mock = $this->getMockBuilder(ExistValidator::className())
                        ->setConstructorArgs(['config' => get_object_vars($validator)])
                        ->setMethods(['createQuery'])
                        ->getMock();
    
                    $mock->expects($this->any())
                        ->method('createQuery')
                        ->willReturn($activeQueryMock);
    
                    $validators[$key] = $mock;
                    break;
                }
            }
            return $validators;
        });
    
    $model->validate();
    

    【讨论】:

      猜你喜欢
      • 2019-01-18
      • 1970-01-01
      • 2017-06-22
      • 2011-11-08
      • 1970-01-01
      • 2013-04-02
      • 2016-08-02
      • 2016-04-07
      • 2011-08-31
      相关资源
      最近更新 更多