Разобраться с ключевым словом "new" в модульном тесте PHP - PullRequest
0 голосов
/ 13 февраля 2019

В моем случае у меня есть класс, такой как:

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 голосов
/ 27 марта 2019

Я решаю эту проблему с помощью примера решения: Фабричный шаблон .

Мне нужно утверждение, поэтому, когда вы получаете новую модель с завода, утверждайте, что это макет.

И как?

Я создаю класс с методом, который может быть одноэлементным сервисом:

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() в тесте.

...