我有以下模型。
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
public static function foo():bool
{
return true;
}
}
为此我做了以下控制器
namespace App\Controler;
use App\Model\Foo;
class MyController
{
public function bar()
{
$value=MyModel::foo();
if($value){
return "OK";
}
throw new \Exception("Foo not true");
}
}
我想测试我的控制器
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use App\Model\MyModel;
use Mockery;
class MyControllerTest extends BaseTestCase
{
public function testBar()
{
$mock=Mockery::mock('alias:'.MyModel::class);
$mock->shouldReceive('foo')->andReturn(false);
/// Rest of thest here
}
}
但当我运行测试时,我得到了以下错误。
PHPUnit 7.5.20 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 1.62 seconds, Memory: 14.00 MB
There was 1 error:
1) Tests\MyControllerTest::testBar
Mockery\Exception\RuntimeException: Could not load mock App\Model\MyModel, class already exists
/var/www/html/vendor/mockery/mockery/library/Mockery/Container.php:226
/var/www/html/vendor/mockery/mockery/library/Mockery.php:118
/var/www/html/tests/MyControllerTest.php:20
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
为了减轻这个错误,如图所示 https:/stackoverflow.coma532669794706711。 我试过了。
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use App\Model\MyModel;
use Mockery;
class MyControllerTest extends BaseTestCase
{
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testBar()
{
$mock=Mockery::mock('alias:'.MyModel::class);
$mock->shouldReceive('foo')->andReturn(false);
/// Rest of thest here
}
}
但还是得到同样的错误信息
根据@mohammad.kaab的回答,我尝试了以下方法。
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use App\Model\MyModel;
use Mockery;
class MyControllerTest extends BaseTestCase
{
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testBar()
{
$this->app->instance(MyModel::class, \Mockery::mock(MyModel::class, function($mock){
$mock->shouldReceive('foo')->andReturn(true);
}));
$myModel = $this->app->make(MyModel::class);
dd($myModel::foo()); // should return true
}
}
但还是不行,因为... \Mockery::mock
模拟一个实例,而不是模拟类本身。因此,我尝试了下面的方法。
public function testBar()
{
$mock=Mockery::mock('alias:'.MyModel::class);
$mock->shouldReceive('foo')->andReturn(false);
/// Rest of thest here
}
但对我来说并不奏效。
也许你可以用这个代码
$this->app->instance(MyModel::class, \Mockery::mock(MyModel::class, function($mock){
$mock->shouldReceive('foo')->andReturn(true);
}));
$myModel = $this->app->make(MyModel::class);
dd($myModel::foo()); // should return true