php - 在 PHP 单元测试中处理“新”关键字
问题描述
就我而言,我有一个课程,例如:
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 类在容器中注册了单例并且不能将模型作为依赖项注入。
如何更改类以更改为可测试类?
LoggerModel 是一个 Doctrine 实体,在 Laravel 框架中使用。
解决方案
我用一个示例解决方案解决了这个问题: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()
函数的服务。
推荐阅读
- javascript - 如何更新属于浏览器本地存储的特定 json 数据对象
- jquery - 无法使用 Javascript 打开 Bootstrap 下拉菜单
- html - 即使指定了索引,XPath $x() 函数也会返回数组
- swiper - 在 Swiper 的垂直模式下设置正确的高度
- c# - 制作索引 0 返回空白字符串的枚举
- ios - 获取 Date() 的下一个工作日
- flutter - 如何在 Flutter 中的 custompaint 上重叠图像?
- android - 如何找到当前设备位置?
- saml-2.0 - 如何将 OAM 配置为 SAML SSO 的服务提供者
- python - 如何在 for 循环中实现池