Я пишу несколько тестов для веб-приложения, и один из них — Сбой при работе & разработка работает нормально.
Это провал:
myMelomanBundle \ Публикация \ CreatePublicationUseCaseTest :: shouldCreateAPublicationOneTimeIfItDoesNotExist
TypeError: Аргумент 1, передаваемый в myDomain \ Entity \ Publication :: setUser (), должен быть экземпляром myDomain \ Entity \ User с указанным нулевым значением, который вызывается в /var/www/melomaniacs/src/myDomain/UseCases/Publication/CreatePublicationUseCase.php на линии 48
CreatePublicationUseCaseTest.php:
<?php
namespace myMelomanBundle\Publication;
use myDomain\Entity\Publication;
use myDomain\UseCases\Publication\CreatePublicationUseCase;
use myMelomanBundle\Repository\UserRepository;
use myMelomanBundle\Repository\PublicationRepository;
use PHPUnit_Framework_MockObject_MockObject;
use Doctrine\ORM\EntityManagerInterface;
use myDomain\Entity\User;
class CreatePublicationUseCaseTest extends \PHPUnit_Framework_TestCase
{
const USER_ID = 2;
const MESSAGE = "message";
const URI = "spotify:uri:47n4in3482nk";
/**
* @var CreatePublicationUseCase
*/
private $createPublicationUseCase;
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
private $userRepositoryMock;
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
private $publicationRepositoryMock;
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
private $aDispatcherMock;
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
private $aEntityMock;
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
private $userMock;protected function setUp()
{
$this->userRepositoryMock = $this->createMock(UserRepository::class);
$this->publicationRepositoryMock = $this->createMock(PublicationRepository::class);
$this->aEntityMock = $this->createMock(EntityManagerInterface::class);
$this->createPublicationUseCase = new CreatePublicationUseCase($this->publicationRepositoryMock, $this->userRepositoryMock, $this->aEntityMock);
$this->userMock = $this->createMock(User::class);
}
protected function tearDown()
{
$this->userRepositoryMock = null;
$this->publicationRepositoryMock = null;
$this->createPublicationUseCase = null;
$this->userMock = null;
}
/** @test */
public function dummyTest()
{
$this->createPublicationUseCase;
}
/** @test */
public function shouldCreateAPublicationOneTimeIfItDoesNotExist()
{
$this->givenAPublicationRepositoryThatDoesNotHaveASpecificPublication();
$this->thenThePublicationShouldBeSavedOnce();
$this->whenTheCreateUserUseCaseIsExecutedWithASpecificParameters();
}
private function givenAPublicationRepositoryThatDoesNotHaveASpecificPublication()
{
$this->publicationRepositoryMock
->method('find')
->willReturn(false);
}
private function thenThePublicationShouldBeSavedOnce()
{
$this->publicationRepositoryMock
->expects($this->once())
->method('create')
->willReturn($this->isInstanceOf(Publication::class));
}
private function whenTheCreateUserUseCaseIsExecutedWithASpecificParameters()
{
$this->createPublicationUseCase->execute(self::USER_ID, self::MESSAGE, null);
}
}
CreatePublicationUseCase.php
<?php
namespace myDomain\UseCases\Publication;
use Doctrine\ORM\EntityManagerInterface;
use myDomain\Entity\Publication;
use myDomain\Entity\User;
use myDomain\PublicationRepositoryInterface;
use myDomain\UserRepositoryInterface;
use myMelomanBundle\Repository\PublicationRepository;
use myMelomanBundle\Repository\UserRepository;
class CreatePublicationUseCase
{
/**
* @var PublicationRepository
*/
private $publicationRepository;
/**
* @var UserRepository
*/
private $userRepository;
private $entityManager;
public function __construct(
PublicationRepositoryInterface $publicationRepository,
UserRepositoryInterface $userRepository,
EntityManagerInterface $entityManager
)
{
$this->publicationRepository = $publicationRepository;
$this->userRepository = $userRepository;
$this->entityManager = $entityManager;
}
public function execute($userId, $message = null, $uri = null)
{
try{
/**
* @var User $user
*/
$user = $this->userRepository->findOneBy(array('id'=>$userId));
\Doctrine\Common\Util\Debug::dump($user);die; => Here
$publication = new Publication();
$publication->setMessage($message == null ? '' : $message);
$publication->setCreatedAt(new \DateTime());
$publication->setUser($user);
$publication->setStatus(0);
$publication->setLink($uri == null ? '' : $uri);
$this->publicationRepository->create($publication);
$this->entityManager->flush();
return $publication;
} catch (\Exception $e) {
return false;
}
}
}
Обратите внимание, что где дамп, он возвращает объект пользователя правильно, просто в тесте он возвращает NULL.
На тесте должен получаться такой же результат для объекта User, как без теста, не должно быть?
Что я делаю не так?
Похоже, ваша проблема исходит из следующей строки CreatePublicationUseCase::execute
$user = $this->userRepository->findOneBy(array('id'=>$userId));
В своем тесте вы проходите в шутку UserRepository
но вы не издеваетесь над выводом findOneBy
,
$this->userRepositoryMock = $this->createMock(UserRepository::class);
Я полагаю, что вы получите желаемые результаты, если вы также будете издеваться над результатами, как показано ниже.
$this->userRepositoryMock
->expects($this->once())
->method('findOneBy')
->will($this->returnValue(<value>));
Других решений пока нет …