【问题标题】:Unsure if I'm using mockery correctly不确定我是否正确使用了嘲弄
【发布时间】:2014-03-25 20:49:50
【问题描述】:

我第一次与 mocking/Mockery 作斗争,我不确定下面的测试是否真的触及我的代码,或者只是测试我所做的 mock?另外,我意识到尽管它的名称如此,但这段代码并不适合存储库模式。我会努力解决这个问题。

班级:

<?php namespace Acme\Cart\Repositories;

class EloquentCartRepository{
    protected $model_name = 'CartModel';
    protected $model;
    public function __construct($model = null)
    {
        $this->model = is_null($model) ? new $this->model_name : $model;
    }

    public function create_visitor_cart($session_id,$type = 'main'){
        return $this->create('visitor',$session_id,$type);
    }
    protected function create($user_type = null,$user_identifier = null,$type = 'main')
    {
        if(is_null($user_identifier)) throw new \Exception('Cannot create create cart, missing user identifier');
        if(is_null($user_type)) throw new \Exception('Cannot create create cart, missing user type');
        if($user_type == 'visitor')
        {
            $this->model->user_session_id = $user_identifier;
        }
        else
        {
            $this->model->user_id = $user_identifier;
        }
        $this->model->type = $type;
        $this->model->save();
        return $this->model;
    }
}

我的测试:

/** @test */
public function create_visitor_cart_calls_internal()
{
    $model = m::mock('Models\CartModel');
    $model->shouldReceive('user_session_id')->with('sess123');
    $model->shouldReceive('type')->with('main');
    $model->shouldReceive('save')->andReturn($model);

    $repository = new EloquentCartRepository($model);
    $created_model = $repository->create_visitor_cart('sess123','main');
    $this->assertEquals('sess123',$created_model->user_session_id);
    $this->assertEquals('main',$created_model->type);
}

这是测试我的课程的正确方法吗?或者这是对 Mockery/mocking 的错误使用?

【问题讨论】:

    标签: php phpunit mockery


    【解决方案1】:

    您应该测试它是否已保存,而不是测试返回的内容。这意味着,-&gt;save() 正在运行。您对-&gt;save() 设置的期望是$model-&gt;shouldReceive('save')-&gt;andReturn($model);。这没有意义,因为代码没有使用-&gt;save() 的返回值。

    在编程中,您通常处理两种类型的方法:命令和查询。查询可以获得一些值,执行一些逻辑并返回一个值。命令可以获取一些值,与外部源(例如数据库)通信并且什么也不返回。查询应该被存根(这意味着,它们不应该对它被调用多少做任何期望,而只对它返回什么做任何期望)并且应该模拟命令(这意味着,它们应该只包含关于多少(以及是否)它的期望被调用)。

    -&gt;save() 方法是一个命令:它与数据库通信。所以应该嘲讽。要模拟对象,请使用 Mockery 的 -&gt;once() 方法。它设定了一个应该被调用一次的期望:

    /** @test */
    public function create_visitor_cart_calls_internal()
    {
        $model = m::mock('Models\CartModel');
        $model->shouldReceive('save')->once();
    
        $repository = new EloquentCartRepository($model);
        $created_model = $repository->create_visitor_cart('sess123','main');
        $this->assertEquals('sess123',$created_model->user_session_id);
        $this->assertEquals('main',$created_model->type);
    }
    

    尽管有它的名字,Mockery 默认是一个存根框架。除非您明确指定诸如 -&gt;once() 之类的期望,否则它不会验证是否调用了方法。

    有关详细信息,请参阅文档:https://github.com/padraic/mockery-docs/blob/master/reference/expectations.rst

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-14
      • 2014-07-19
      • 2017-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多