Reputation: 3589
I'm trying to do a unit test for a signup method and im following this guide. I'm fairly new to unit testing.
i keep getting
1) App\Tests\Controller\SignUpControllerTest::testSignUp Error: Cannot instantiate interface Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface
/Applications/MAMP/htdocs/my_project/tests/Controller/SignUpControllerTest.php:19
I just don't think im doing this unit test right. Here is what i have. I'm not sure on what im doing. All i want to do is test the signup method.
UserController.php
public function signup(Request $request, UserPasswordEncoderInterface $passwordEncoder )
{
$user = new User();
$entityManager = $this->getDoctrine()->getManager();
$user->setEmail($request->get('email'));
$user->setPlainPassword($request->get('password'));
$user->setUsername($request->get('username'));
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute('login');
}
SignUpControllerTest.php
namespace App\Tests\Controller;
use App\Entity\Product;
use App\Controller\UserController;
use App\Entity\User;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class SignUpControllerTest extends WebTestCase
{
public function testSignUp()
{
$passwordEncoder = new UserPasswordEncoderInterface();
$user = new User();
$user->setEmail('[email protected]');
$user->setPlainPassword('owlhunter');
$user->setUsername('BarnMan');
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$userRepository = $this->createMock(ObjectRepository::class);
$userRepository->expects($this->any())
->method('find')
->willReturn($user);
$objectManager = $this->createMock(ObjectManager::class);
// use getMock() on PHPUnit 5.3 or below
// $objectManager = $this->getMock(ObjectManager::class);
$objectManager->expects($this->any())
->method('getRepository')
->willReturn($userRepository);
$userController = new UserController($objectManager);
$this->assertEquals(2100, $userController->signupTest());
}
}
Upvotes: 2
Views: 4981
Reputation: 849
WebTestCase :
Application tests are PHP files that typically live in the tests/Controller/ directory of your application it tell Symfony that we need the tools necessary to talk to our application as if we were doing so via HTTP.
KernelTest
use for to fetch a service from the dependency injection container it help you creating and booting the kernel in your tests
that's why I recommend you to use KernelTestCase
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class SignUpControllerTest extends KernelTestCase
{
private $passwordEncoder;
protected function testSignUp(): void
{
self::bootKernel();
$this->passwordEncoder= self::getContainer()->get('Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface');
}
public function addShoes3()
{
$passwordEncoder = $this->passwordEncoder;
//continue
}
}
Upvotes: -1
Reputation: 1828
The error is very clear. In the first line of your testSignUp method, you are creating an instance out of an interface, which cannot be done in PHP.
To create a usable object out of an interface in unit testing, create a mock object of it. Read PHP unit docs for that.
Upvotes: 2