【问题标题】:Deal with 'new' keyword in PHP unit test在 PHP 单元测试中处理“新”关键字
【发布时间】:2019-07-07 00:20:30
【问题描述】:

就我而言,我有一个类,例如:

class Logger
{
/**
 * @var EntityManager
 */
protected $entityManager;

public function __construct(EntityManager $entityManager)
{
    $this->entityManager = $entityManager;
}

/**
 * @param Model $model
 */
public function log(Model $model)
{
    $logEntity = new LogEntity();
    $logEntity->setOrder($model->getOrder());
    $logEntity->setType($model->getType());
    $logEntity->setScore($model->getScore());
    $logEntity->setCreated(new DateTime());
    $logEntity->setModified(new DateTime());

    $this->entityManager->persist($logEntity);
    $this->entityManager->flush();

    return $logEntity;

}

Logger 类不可测试,因为在我的代码中存在“new”关键字,另一方面,Logger 类和 EntityManager 类在容器中注册了 singleton 并且无法将模型作为依赖项注入。

如何更改类以更改为可测试类?

LoggerModel 是一个 Doctrine 实体,在 Laravel 框架中使用。

【问题讨论】:

    标签: php laravel unit-testing doctrine phpunit


    【解决方案1】:

    我用一个示例解决方案解决了这个问题:Factory Pattern

    我需要断言,所以当从工厂获取新模型时,将其断言为模拟。

    怎么做?

    我创建了一个类,其方法可以是单例服务:

    class LogFactory
    {
        public function makeLogEntity()
        {
            return new LogEntity();
        }
    }
    

    在另一个服务中,注入工厂类:

    class Logger
    {
    /**
     * @var EntityManager
     */
    protected $entityManager;
    
    /**
     * @var LogFactory
     */
    protected $logFactory;
    
    public function __construct(EntityManager $entityManager, LogFactory $logFactory)
    {
        $this->entityManager = $entityManager;
        $this->logFactory = $logFactory
    }
    
    /**
     * @param Model $model
     */
    public function log(Model $model)
    {
        $logEntity = $this->logFactory->makeLogEntity();
        $logEntity->setOrder($model->getOrder());
        $logEntity->setType($model->getType());
        $logEntity->setScore($model->getScore());
        $logEntity->setCreated(new DateTime());
        $logEntity->setModified(new DateTime());
    
        $this->entityManager->persist($logEntity);
        $this->entityManager->flush();
    
        return $logEntity;
    
    }
    

    现在我有一个可以模拟的服务并在测试中调用 $mock->willReturn() 函数。

    【讨论】:

      猜你喜欢
      • 2014-02-28
      • 1970-01-01
      • 2010-12-21
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 2015-04-27
      相关资源
      最近更新 更多