我正在尝试测试一个图像导入器,该程序获取文件并提交附加了该图像的表单。测试的那部分似乎是它失败的部分,我不确定如何解决它。
我理解不"嘲笑你不拥有的东西"的概念,但是如果不承认对私有方法的调用,insertImageThroughForm
测试不起作用。
我收到以下错误:
75 ! imports image assets
method call:
- submit(["file" => ["assetFile" => ["file" => SymfonyComponentHttpFoundationFileUploadedFile:0000000027d380bc00007f8c6cad27ec Object (
'test' => false
'originalName' => 'picco.jpg'
'mimeType' => 'application/octet-stream'
'size' => null
'error' => 0
)]]], false)
on DoubleSymfonyComponentFormFormP22 was not expected, expected calls were:
- submit(exact(["file" => ["assetFile" => ["file" => DoubleSymfonyComponentFinderSplFileInfoP19:0000000027d3807500007f8c6cad27ec Object (
'objectProphecy' => ProphecyProphecyObjectProphecy Object (*Prophecy*)
'relativePath' => null
'relativePathname' => null
)]]]), exact(false))
- submit(exact(["file" => ["assetFile" => ["file" => DoubleSymfonyComponentFinderSplFileInfoP20:0000000027d3803000007f8c6cad27ec Object (
'objectProphecy' => ProphecyProphecyObjectProphecy Object (*Prophecy*)
'relativePath' => null
'relativePathname' => null
)]]]), exact(false))
ImageImporterSpec.php
const TEMP_PATH = '/tmp/crmpicco/imageImporter';
function it_imports_image_assets(
Category $category,
AssetFactory $assetFactory,
Asset $asset,
Finder $finder,
SplFileInfo $file1,
SplFileInfo $file2,
FormFactory $formFactory,
Form $form
) {
$category->getId()->willReturn(14);
$createTempPathFilesystem = new Filesystem();
$createTempPathFilesystem->mkdir(self::TEMP_PATH);
$createTempPathFilesystem->mkdir(self::TEMP_PATH . DIRECTORY_SEPARATOR . 'courses');
$imageImportPath = self::TEMP_PATH . DIRECTORY_SEPARATOR . 'courses/';
$createTempPathFilesystem->touch($imageImportPath . 'picco.jpg');
$createTempPathFilesystem->touch($imageImportPath . 'morton.jpg');
$finder->files()->willReturn($finder);
$finder->in($imageImportPath)->willReturn($finder);
$finder->getIterator()->willReturn(new ArrayIterator([
$file1->getWrappedObject(),
$file2->getWrappedObject(),
]));
$file1->getPathname()->willReturn($imageImportPath . 'picco.jpg');
$file2->getPathname()->willReturn($imageImportPath . 'morton.jpg');
$assetFactory->createForCategory(14)->willReturn($asset);
$formFactory->create('category_asset', $asset, ['csrf_protection' => false])->willReturn($form);
$form->submit(['file' => ['assetFile' => ['file' => $file1->getWrappedObject()]]], false)->shouldBeCalled();
$form->submit(['file' => ['assetFile' => ['file' => $file2->getWrappedObject()]]], false)->shouldBeCalled();
$this->importImageAssets('courses/', $category)->shouldBeCalled();
}
ImageImporter.php
public function importImageAssets($importDirectory, Category $category)
{
$finder = new Finder();
$finder->files()->in($importDirectory);
if (count($finder) > 0) {
foreach ($finder as $image) {
$filename = $image->getBasename('.' . $image->getExtension());
$filepath = $importDirectory . '/' . $image->getFilename();
$asset = $this->assetFactory->createForCategory($category->getId());
$asset->setName($filename);
$this->insertImageThroughForm($asset, $filepath);
$this->entityManager->persist($asset);
}
$this->entityManager->flush();
}
}
private function insertImageThroughForm(Asset $asset, $filePath)
{
$form = $this->formFactory->create('category_asset', $asset, ['csrf_protection' => false]);
$uploadedFile = new UploadedFile($filePath, basename($filePath));
$form->submit(['file' => ['assetFile' => ['file' => $uploadedFile]]], false);
}
您正在测试的与其说是单元测试,不如说是集成测试。PhpSpec 不适合集成测试,而仅适用于低单元测试。为什么是集成测试?因为您使用的是真正的文件系统,它是外部服务,也很少有第三方库,如Filesystem
和Finder
。
您正在尝试模拟Finder
但Finder
直接在方法中初始化,因此无法模拟。您需要将Finder
作为类的依赖项注入。