Php 嘲弄雄辩的模型
我已经翻阅了数百页,我似乎找不到与我在这些页上找到的工作示例不同的地方 我使用的是Laravel4.2、PHPUnit 4.3.1和Composer的最新嘲弄。我正在我的控制器AppController上运行PHPUnit测试,我想通过模拟模型截取一个有说服力的数据库save()。虽然在创建Mock时没有抛出错误,但是Mock也没有附加到我的模型,因此仍在创建行 我错过了什么?谢谢 mockry中的错误:Php 嘲弄雄辩的模型,php,unit-testing,laravel,phpunit,mockery,Php,Unit Testing,Laravel,Phpunit,Mockery,我已经翻阅了数百页,我似乎找不到与我在这些页上找到的工作示例不同的地方 我使用的是Laravel4.2、PHPUnit 4.3.1和Composer的最新嘲弄。我正在我的控制器AppController上运行PHPUnit测试,我想通过模拟模型截取一个有说服力的数据库save()。虽然在创建Mock时没有抛出错误,但是Mock也没有附加到我的模型,因此仍在创建行 我错过了什么?谢谢 mockry中的错误:mockry\Exception\InvalidCountException:Method
mockry\Exception\InvalidCountException:Method save()from mockry\u 0\u EventRsvp应该精确调用1次,但调用0次。
// Located at /app/tests/app/AppControllerTest.php
class AppControllerTest extends TestCase {
public function setUp() {
parent::setUp();
Session::start();
Mail::pretend();
}
public function tearDown() {
parent::tearDown();
\Mockery::close();
}
public function testPostApp() {
$myvar = array();
$this->mock = \Mockery::mock('Eloquent','EventRsvp');
$this->app->instance('EventRsvp', $this->mock);
$this->mock
->shouldReceive('save')
->once()
->andReturn('true');
$response = $this->call('POST', '/3tDYSL0', $myvar);
}
}
//位于/app/models/EventRsvp.php
使用而不是调用neweventrsvp
您可能希望创建一个将为控制器提供EventRsvp
s的存储库,然后您可以轻松地模拟回购协议并将其注入,而不是真正的回购协议
正如你所知,虽然实现你所尝试的是可行的,但我不会这么做:
$mock = Mockery::mock('overload:EventRsvp');
$mock->shouldReceive('save')->once()->andReturn(true);
$response = $this->call('POST', '/3tDYSL0', $myvar);
这是带有mockry的实例模拟,它将捕获控制器中的
新EventRsvp
调用,并使用该$mock
而不是真实模型。但同样,使用依赖注入,这是您想要的。您的代码就是不可测试代码的示例。了解依赖注入,以及为什么在控制器中使用新类
“不好”。你不能通过mock引用那个新类
,你需要将mock注入到你的控制器中。@JarekTkaczyk-Hmm,阅读后,是的,你是对的。我的整个代码库都是这样写的,看起来我面前有一个大任务。你能回答你的评论吗?看起来很好,可以作为我的答案。感谢您提供的解决方案-将我的整个代码库转换为使用DI需要一段时间,所以我必须在这样做时使用解决方案。但是,当我使用您显示的重载
时,会出现以下错误:PHP致命错误:对非对象调用成员函数mockry_getExpectations()
。谷歌上似乎没有其他人有这个问题……有什么想法吗?好的-添加了路径,所以现在它的mockry::mock('重载:app\models\EventRsvp')代码>并且运行时没有mockry\u getexpections()
错误或我的原始错误!但是,EventRsvp行仍在创建中。如何防止这种情况发生?看起来添加重载:
不尊重once()
调用,这就是为什么不再存在原始异常的原因。如果我将mock更改为不存在的东西,比如mockry::mock('重载:adsfafdsf')
测试仍然成功运行,没有错误,即使该方法从未在控制器中调用。不,它只尊重一次
。但是,如果您碰巧注入EventRsvp
或在其他地方实例化它,则可能会导致问题。因此,请确保不要将其注入构造函数,或者最好使用DI nowahh,就是这样,我将其注入构造函数中,这是我所有测试的混合。现在可以正常工作了。感谢您展示了正确的方法、DI和临时解决方案!
// Located at /app/models/EventRsvp.php
<?
class EventRsvp extends Eloquent {
protected $guarded = array('id');
use Illuminate\Database\Eloquent\SoftDeletingTrait;
protected $dates = ['deleted_at'];
public function relationshipone()
{
return $this->belongsTo('RelationshipOne','idone');
}
public function relationshiptwo()
{
return $this->belongsTo('RelationshipTwo','idtwo');
}
}
?>
$mock = Mockery::mock('overload:EventRsvp');
$mock->shouldReceive('save')->once()->andReturn(true);
$response = $this->call('POST', '/3tDYSL0', $myvar);