Php 依赖注入最佳实践
我正在进行单元测试,花了好几天的时间寻找答案,却一个也没有找到。 我正在写一个应用程序,它可以读取文件系统,搜索图像和视频。 然后我想为每个图像实例化一个模型Php 依赖注入最佳实践,php,unit-testing,dependency-injection,service-locator,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) { $
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() ...
}
然后,将从图像|视频实例中检索各种数据,并将其存储在数据库中
现在,最佳做法是什么?我是使用依赖注入,还是像上面的例子那样简单地实例化模型?
那么我如何对这个类进行单元测试呢?如果我理解正确的话,由于blackbox测试和封装,我应该模拟InstanceEmodels()方法,但不应该测试或模拟私有方法 如果我插入一个工厂,它可以实例化图像模型或视频模型:
class A
{
public function __construct (Factory $mediaFactory)
{
$this->factory = $mediaFactory;
}
private function instantiateModels ($type, $file)
{
return $this->factory->build($type, $file);
}
...
}
然后我可以模拟工厂,但据我所知,这将是一个服务定位器,这是一种反模式
在这种情况下我该怎么办
编辑:
或者问题是,我的A班想要一次做太多的事情,因此不符合“单一责任”原则?
我可以创建一个B类来搜索媒体文件吗?一个C类是工厂,可以实例化图像和视频实例,a类应该将B类和C类作为依赖项吗?
但是,同样,我如何对factory类进行单元测试?为什么不将A对象传递到factory中,然后factory创建新的媒体实例?工厂应该获得从公开的公共API创建新模型所需的一切。@frz3993你说,我应该向工厂传递一个实例吗?只是一个建议。具有类似
函数createMediaFromA(a){}
的方法的工厂。因此,您可以使用模拟A测试工厂,并将对象创建的责任委托给工厂。而A将不再负责创建对象。因此,A将不再依赖于工厂。为什么不将A对象传递到工厂,工厂将创建新的媒体实例?工厂应该获得从公开的公共API创建新模型所需的一切。@frz3993你说,我应该向工厂传递一个实例吗?只是一个建议。具有类似函数createMediaFromA(a){}
的方法的工厂。因此,您可以使用模拟A测试工厂,并将对象创建的责任委托给工厂。A将不再承担创建对象的责任。因此,A将不再依赖于工厂。