使用 mockeryBuilder() 测试 Yii2 中没有数据库的现有验证器



我想在不连接到 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());
  }
}

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

Yii2 ExistValidator 使用 ActiveQuery::exists() 来检查是否存在,你应该将生成的验证器替换为 mockobject,其中方法 createQuery 返回 ActiveQuery 的 mockobject 其中 ::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();

最新更新