依赖注入最佳实践

时间:2017-04-16 08:20:15

标签: php unit-testing dependency-injection service-locator

我正在进行单元测试,并且搜索天数以找到答案,但我没有找到答案。 我正在编写一个应用程序来读取文件系统,搜索图像和视频。 然后我想为每个图像实例化一个模型。

class A 
{
   private function readFS ($path)
   {
       ... read file system, collect the media into an array ...
       foreach($files as $currentFile) {
            $return[$file->type][] = $file;
       }
       return $return;
   }

   // type can either be Image or Video
   private function instantiateModels ($type, $file)
   {
    return new $type(['file' => $file]);
   }

   public function processFolder ($path)
   {
    $files = $this->readFS($path);

    foreach($files as $type => $files) {
        foreach($files as $currentFile) {
            $type[] = $this->instantiateModels($type, $currentFile);
        }
    }

    ... then every media instance is saved to the database by calling it's save method: e.g.: Image::save() ...
}

然后将从Image |中检索各种数据视频实例并将存储在数据库中。

现在,最佳做法是什么? 我是否使用依赖注入,或者只是像上面的例子中那样实例化模型?
那我该如何对这个班级进行单元测试呢?如果我理解正确,因为黑盒测试和封装,我应该模拟instantiateModels()方法,但不应该测试或模拟私有方法。

如果我依赖注入工厂,可以实例化Image模型或视频模型:

class A 
{
      public function __construct (Factory $mediaFactory)
      {
             $this->factory = $mediaFactory;
      }

      private function instantiateModels ($type, $file)
      {
            return $this->factory->build($type, $file);
      }

      ...
}

然后我可以嘲笑工厂,但据我所知,这将是一个服务定位器,这是一种反模式。

在这种情况下我该怎么办?

编辑: 或许问题是,我的A级想要同时做太多事情,因此不符合“单一责任”原则? 我可以创建一个用于搜索媒体文件的B类和一个工厂的C类,它可以实例化Image和Video实例,而A类应该将B类和C类作为依赖项? 但话又说回来,我如何对工厂级进行单元测试?

0 个答案:

没有答案