Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 嘲弄雄辩的模型_Php_Unit Testing_Laravel_Phpunit_Mockery - Fatal编程技术网

Php 嘲弄雄辩的模型

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

我已经翻阅了数百页,我似乎找不到与我在这些页上找到的工作示例不同的地方

我使用的是Laravel4.2、PHPUnit 4.3.1和Composer的最新嘲弄。我正在我的控制器AppController上运行PHPUnit测试,我想通过模拟模型截取一个有说服力的数据库save()。虽然在创建Mock时没有抛出错误,但是Mock也没有附加到我的模型,因此仍在创建行

我错过了什么?谢谢

mockry中的错误:
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);