我在使單元測試正常工作時遇到了一些麻煩。我正在測試使用由工廠創建的服務的控制器。我想要實現的是用模擬服務替換工廠,這樣我就可以在不使用活動數據庫連接的情況下執行測試。對象模仿 - 如何用服務管理器中的服務替換工廠?
的設置
在我的服務管理器的配置文件,我點了一個工廠。 工廠要求在單元測試期間不想使用的活動數據庫連接。
Namespace MyModule;
return [
'factories' => [
MyService::class => Factory\Service\MyServiceFactory::class,
],
];
注:我已經改變了類名和用於說明目的簡化配置。
該服務使用一個映射器,我現在不會進入,因爲它與情況無關。映射器在他們自己的測試用例中進行測試。該服務本身也有它自己的測試用例,但需要出現在控制器的工作中。
控制器操作只是從服務接收信息。
Namespace MyModule\Controller;
use MyModule\Service\MyService;
use Zend\Mvc\Controller\AbstractActionController;
class MyController extends AbstractActionController
{
/**
* @var MyService
*/
private $service;
/**
* @param MyService $service
*/
public function __construct(MyService $service)
{
$this->service = $service;
}
/**
* Provides information to the user
*/
public function infoAction()
{
return [
'result' => $this->service->findAll(),
];
}
}
注:同樣,我已經改變類名和簡化用於說明目的的示例。
我已經試過
在我的測試用例我試圖覆蓋所需的工廠是這樣的:
/**
* @return \Prophecy\Prophecy\ObjectProphecy|MyService
*/
private function mockService()
{
$service = $this->prophesize(MyService::class);
$service->findAll()->willReturn(['foo', 'bar']);
return $service;
}
/**
* @param \Zend\ServiceManager\ServiceManager $services
*/
private function configureServiceManager(ServiceManager $services)
{
$services->setAllowOverride(true);
$services->setService(MyService::class, $this->mockService()->reveal());
$services->setAllowOverride(false);
}
乍一看,這看起來不錯,但它不工作。它似乎將服務附加到服務經理的服務列表中,而不是壓倒工廠。
更改$services->setService
到$services->setFactory
需要我建立另一個工廠。我能做的就是創建一個工廠,將一個模擬映射器注入服務器,但感覺不對。我正在測試控制器,而不是服務或映射器,所以我試圖避免這樣的複雜解決方案來保持我的測試用例簡單明瞭。
有沒有關於我的情況的選擇?是否有可能在服務管理器中覆蓋具有服務的工廠,或者我看錯了嗎?
我在我的問題中聲明我不願意「建立另一個工廠」。這是沒有必要的,因爲我顯然能夠爲它寫一個閉包。 –