Php 如何使用mocky在内腔中使用mock

Php 如何使用mocky在内腔中使用mock,php,phpunit,mockery,Php,Phpunit,Mockery,如何在内腔框架中使用模拟? 我使用内腔框架。内腔的文件非常简单。我不知道如何用嘲弄或外表来嘲弄模特。我尝试了一些方法,但没有人奏效。我想模拟updatePassword方法中的UserModel的两点。 请帮帮我 用户模型 use Illuminate\Database\Eloquent\Model; class UserModel extends Model { // connection protected $connection = 'db_user'; // ta

如何在内腔框架中使用模拟? 我使用内腔框架。内腔的文件非常简单。我不知道如何用嘲弄或外表来嘲弄模特。我尝试了一些方法,但没有人奏效。我想模拟updatePassword方法中的UserModel的两点。 请帮帮我

用户模型

use Illuminate\Database\Eloquent\Model;
class UserModel extends Model {
    // connection
    protected $connection = 'db_user';
    // table
    protected $table = 'user';
    // primarykey
    protected $primaryKey = 'id';
}
用户逻辑

class UserLogic {
    public static updatePassword($id, $password) {
        // find user
        $user = UserModel::find($id); // mock here**************************************
        if (empty($user)) {
            return 'not find user';
        }
        // update password
        $res = UserModel::where('id', $id)
               ->update(['password' => $password]); // mock here*****************************
        if (false == $res) {
            return 'update failed';
        }
        // re Login
        $res2 = LoginModel::clearSession();
        if (false == $res2) {
            return false;
        }
        return true;
    }
}
phpunit测试1不起作用

use Mockery;
public function testUpdatePassword() {
    $mock = Mockery:mock('db_user');
    $mock->shouldReceive('find')->andReturn(false);
    $res = UserLogic::updatePassword(1, '123456');
    $this->assertEquals('not find user', $res);
}
use Mockery;
public function testUpdatePassword() {
    $mock = Mockery::mock('alias:UserModel');
    $mock->shouldReceive('find')->andReturn(null);
    $res = UserLogic::updatePassword(1, '123456');
    $this->assertEquals('not find user', $res);
}
phpunit试验2

// BadMethodCallException: Method Mockery_0_Illuminate_DatabaseManager::connection() does not exist on this mock object
use Illuminate\Support\Facades\DB;
public function testUpdatePassword() {
    DB::shouldReceive('select')->andReturnNull();
    $res = UserLogic::updatePassword(1, '123456');
    $this->assertEquals('not find user', $res);
}
phpunit测试3不起作用

use Mockery;
public function testUpdatePassword() {
    $mock = Mockery:mock('db_user');
    $mock->shouldReceive('find')->andReturn(false);
    $res = UserLogic::updatePassword(1, '123456');
    $this->assertEquals('not find user', $res);
}
use Mockery;
public function testUpdatePassword() {
    $mock = Mockery::mock('alias:UserModel');
    $mock->shouldReceive('find')->andReturn(null);
    $res = UserLogic::updatePassword(1, '123456');
    $this->assertEquals('not find user', $res);
}
试试这个:

    $mock = Mockery::mock('alias:\NamespacePath\To\UserModel');
    $mock->shouldReceive('find')->andReturn(null);
    $this->app->instance('\NamespacePath\To\UserModel', $mock);
请注意,当您想要模拟公共静态函数时,可以使用关键字
alias
。如果要模拟对象(使用
new
创建),则可以使用关键字
重载(

我面临的另一个困难是,我们仍然在其他测试中使用模拟,在这些测试中,我不想再使用模拟,这使得测试失败。模拟持久性与类的加载有关。这在全局范围内发生一次,并一直持续到测试过程终止(从这里开始:)。因此,无论先发生什么(将类用作模拟对象或真实对象),都将定义如何调用该类,此后您不能再对其进行更改。在我之前链接的博客文章中,Alexandros Gougousis谈到了如何通过在自己的进程中运行模拟测试和禁用全局状态保存来规避这个问题。我尝试了他的方法,但有一些问题,但我也没有花太多时间。为什么不呢?因为我找到了不同的解决方案:在
phpunit.xml
中设置变量
processIsolation=“true”
。这就解决了问题。我应该注意到,这将每个测试的持续时间增加了约0.5秒,因此,如果让Alexandros方法运行,它可能会更有效,因为它只会在自己的流程中使用模拟运行测试


旁注:这也适用于作为测试基类的Lumen TestCase。

这里的内容相同。我已经尝试过PHPUnit、mockry、AspectMock,但仍然无法使mocking用于此框架和ORM模型。使用普通PHPUnit测试用例而不是Lumen测试用例对我有效,请参阅