在PHP单元测试中处理'new'关键字

时间:2019-02-13 08:27:44

标签: php laravel unit-testing doctrine phpunit

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

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框架中使用。

1 个答案:

答案 0 :(得分:0)

我通过一个示例解决方案来解决此问题:工厂模式

我需要断言,因此当从工厂获得新模型时,将其断言为模拟。

又如何?

我创建的类的方法可以是单例服务:

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()函数。