對不起我的問題很長。如何用Symfony在serviceTest中模擬EntityManager?
如何嘲笑的EntityManager延長KernelTestCase服務測試?現在
,解釋和我的測試...
我使用Symfony3.2。我的應用是標準的。我有一些控制器,我使用WebTestCase來測試它們。
Generaly,我控制器驗證參數,調用服務/管理人員,處理一些變量,並推動他們查看和我的測試是非常簡單的延長WebTestCase測試。
/**
* Test New Game Action
*/
public function testFooAction(){
//We mock the Service
$fooService = $this
->getMockBuilder(GameService::class)
->disableOriginalConstructor()
->getMock();
$fooService->expects(self::once())
->method('barMethod')
->willReturn($result);
//We create the client
$client = static::createClient();
$container = $client->getContainer();
//I put my mock here
$container->set('app.game-service', $fooService);
//I launch the request
$client->request('GET', '/foo');
//I handle the response
$response = $client->getResponse();
//I do some tests like this one
self::assertEquals(200, $response->getStatusCode());
}
正如你所看到的,我不叫EntityManger,因爲我用服務這些線路把我的服務的模擬
//We create the client
$client = static::createClient();
$container = $client->getContainer();
//I put my mock here
$container->set('app.game-service', $fooService);
我嘲笑實體管理中存在的問題我的服務。我的控制器已通過測試,但未通過我的服
這裏的構造函數初始化一個簡單的保護財產的EntityManager。問題是這樣的保護你會看的更遠......
/**
* FooService constructor.
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
測試我的服務,這是我最初的代碼:
<?php
class FooServiceTest extends KernelTestCase
{
/**
* Foo Service.
*
* @var FooService
*/
private $fooService;
/**
* Prepares the environment before running each test.
*/
protected function setUp()
{
parent::setUp();
self::bootKernel();
$this->fooService = static::$kernel->getContainer()
->get('app.foo-service') //HERE IS HOW I HANDLE MY SERVICE TO TEST IT
;
}
testStart完美的作品,有一定的數據庫交互。
我知道我可以測試期間回滾數據。但我想嘲弄的EntityManager 驗證commit
方法的召喚。
我試試這個來模擬實體管理器在我的設置:
protected function setUp()
{
parent::setUp();
$entityManager = $this
->getMockBuilder('Doctrine\ORM\EntityManager')
->disableOriginalConstructor()
->getMock();
$entityManager
->expects(once()) // I WANT EXACTLY ONE CALL TO COMMIT METHOD
->method('commit')
->willReturn(null);
self::bootKernel();
$container = static::$kernel->getContainer();
$container->set('doctrine.orm.entity_manager', $entityManager); // THIS LINE DOES NOTHING <=======
$this->gameService = static::$kernel->getContainer()
->get('app.game-service')
;
帖碼不起作用。模擬不到位。我仍然擁有真正的entityManager。我認爲這是因爲集裝箱已經關閉了。做到這一點是螺母有用設置
就像一個野蠻人,我EntityManager的屬性更改爲公共
而且我這樣做:
protected function setUp()
{
parent::setUp();
$entityManagerMock = $this
->getMockBuilder('Doctrine\ORM\EntityManager')
->disableOriginalConstructor()
->getMock();
$entityManagerMock
->expects(once()) // I WANT EXACTLY ONE CALL TO commit METHOD
->method('commit')
->willReturn(null);
self::bootKernel();
$this->gameService = static::$kernel->getContainer()
->get('app.game-service')
;
$this->gameService->entityManager = entityManagerMock;
它完美。測試可以運行。但是,這不是一個很好的做法,在公共財產一個EntityManager
我的問題是:如何嘲笑的EntityManager在服務測試?
(對不起,我的英語不流利)
我認爲你應該選擇你的測試是一個單元測試(你會模擬你的依賴或WebTestCase,在這種情況下,你應該使用測試數據庫並且像平常一樣使用你的應用程序而不嘲笑。我也喜歡「像野蠻人一樣,我將entityManager屬性更改爲公開」 – mickadoo