I have the following very simple test:
use AppBundle\Controller\AdminFriendController;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class AdminFriendTest extends WebTestCase {
public function testFriendEntry() {
$client = static::createClient();
$crawler = $client->request('GET', '/Admin/Friend/Enter');
}
}
When it runs, the output of the test is the entire page from the GET request at /Admin/Friend/Enter. I was expecting just the phpUnit header and a "R" for risky test since I have no assertions. I have also tried this with the entire test written, and I get the same result. I have removed all other code here that does not change the result to simplify the question.
I expected PHPUnit to suppress all that HTML and only provide me with the useful nugget of information. Can anyone tell me why this is producing so much output?
Thank you!
Related
I created register service and I want test that method. In the browser var_dump return true and phpspec return false.. Why ? Any Ideas?
Service : http://pastebin.com/9hYX7S14
Phpspec : http://pastebin.com/xm5NLYyG
Please help.
You need to stub (or mock) all your dependencies:
function it_check_user_exist_in_system(
Registry $doctrine,
ObjectRepository $repository,
User $user
)
{
$doctrine->getManager()->willReturn($doctrine);
$doctrine->getRepository('AcmeUserBundle:User')->willReturn($repository)
$repository->findOneBy(array('username'=>'user1'))->willReturn($user);
$this->checkUser('user1')->shouldReturn(true);
}
You're trying to get the result from a Mocked object.
You're best bet for testing this method is to test using a should be called assertion on the mocked object.
This is not a unit test its functional/acceptance test.
I have wrote a testcase with a longer setUp which looks something like this:
public function setUp(){
$this->manager = $this->get('strego_tipp.invalidation_manager');
$mockEm = m::mock('Doctrine\Common\Persistence\ObjectManager');
$this->setAttribute($this->manager, 'em', $mockEm);
/* .... additional setup stuff ....*/
}
protected function get($service){
return $this->getContainer()->get($service);
}
This is just the setup, and now I have 2 tests in my testfile:
public function test_it_collects_not_duplicate_betRounds(){
$this->assertCount(0, $this->manager->betRounds);
$this->call($this->manager,'collectBetRoundWorkload', $this->game1);
$this->call($this->manager,'collectBetRoundWorkload', $this->game2);
$this->manager->collectBetRoundWorkload($this->game1);
$this->manager->collectBetRoundWorkload($this->game2);
$this->assertCount(2, $this->manager->betRounds);
}
public function test_it_collects_all_bets_to_update(){
$this->assertCount(0, $this->manager->bets);
$this->call($this->manager,'collectBetWorkload', $this->game1);
$this->manager->collectBetWorkload($this->game1);
$this->assertCount(3, $this->manager->bets);
}
When running the test, the second testcase always fails because within the setup there is no service named 'strego_tipp.invalidation_manager' in the container. Although the service was available in the first test. It is also independent from the actual testcase because I can change the order of the tests and still the service is not in the container for the second testcase. This seems to me like a very random problem and I can't get my head around it.
I solved that issue by cleaning cache because I was on prod environment:
$app/console cache:clear --env=prod
Hope it helps :)
I make some functional test with Symfony 2 and phpunit.
But i've some trouble with a Service.
Let me explain.
During my run test, i want to use some service used by the application. So i juste set my setUp function for setting the kernel :
static::$kernel = static::createKernel();
static::$kernel->boot();
$this->objectFactory = static::$kernel->getContainer()->get('some.application.objectfactory');
So i've this and in my function i need to used a service that return an object so i call my service like that
$var = $this->objectFactory->getObject($id);
and obviously in my tearDown function i just :
protected function tearDown()
{
$this->client->restart();
unset($this->client, $this->objectFactory);
}
So my problem is when i run a test i've this message :
Symfony\Component\DependencyInjection\Exception\InactiveScopeException: You cannot create a service ("request") of an inactive scope ("request").
And i can't find a way to solve this.
Did someone have any idea ??
My version of Symfony is 2.2.1 and my version of phpunit is 3.7.19
If someone can help me, i could be very happy.
I'm sorry if my English isn't so good.
EDIT
Maybe it could help someone, in the service i used that : :
$request = $this->container->get('request');
It seems to be the reason why it dosen't work, when i remove it, it doesn't say the error, but they still doesn't work.
EDIT
#Cyprian
According to you have change my code for what i want.
So i just add to my service, in the function that i want, the client (Client web test case), and then inside the function i just add this :
if (isset($client)) {
$request = $client->getRequest();
} else {
$request = $this->container->get('request');
}
So in my function where i call the service i've just this :
public function getObject($id)
{
//Get the service from the kernel
$service = static::$kernel->getContainer()->get('service');
$object = $service->getObject($id, $this->client);
}
and it works fine like this
#nifr
Your idea doesn't work for me, but i think your idea wasn't wrong, they just not works in my case
However Thanks for your help, i'm happy i works now, and i expect that post could help someone else
Try get request from the client, not service container:
$request = $this->client->getRequest();
In that way you can also get kernel and/or container:
$kernel = $this->client->getKernel();
$container = $this->client->getContainer();
One more useful tip: kernel from the client is rebooted between each two requests. So, for example if you pass your mock to client's container and do some request, in next request (after the first one) the container will not contain your mock.
There is no request available in phpUnit as long as you don't construct one.
If you want to test a request. create it like this:
use Symfony\Component\HttpFoundation\Request;
protected $request;
public function setUp()
{
// ...
$this->request = new Request();
// ... modify your request acccording to your needs
}
and add/call a setter in your Service using the request.
$service = $this->kernel->getContainer()->get('your_service')
$service->setRequest($this->request);
or create a Functional Test with WebtestCase.
I want to mock a service that is required in a class constructor. I have an exception of PHPUnit : MyService is required, Mock_MyService_0afc7fc1 given.
But with the Request, EntityManager or other Symfony 2 component, I haven't this issue.
Here is my Class's construct :
use Acme\Bundle\Service\MyService;
use Symfony\Component\HttpFoundation\Request;
...
public function __construct(MyService $service, Request $request)
{
and my mock :
...
$service = $this->getMock('MyService');
$class = new Class($service, $request);
It's impossible to mock our own service ? Only Symfony 2 component ?
PS : If I delete MyServicelike that : public function __construct($service, Request $request), this works. But I want to define my variable with it :(
The issue is that PHPUnit at the time of the test execution can't find (or autoload) your MyService class.
That means that you'll probably run into the same issues with other Mocking libraries as all of them require the original class to exist to scan it and create the mock.
It happens because you need to tell PHPUnit the Fully-Qualified Class Name.
Change your code to $this->getMock("\Acme\Bundle\Service\MyService"); and it should work out.
(Still, give mockery a try. It's a nice library)
I want to add log output to all test messages.
$this->assertTrue(FALSE, "This assertion is False.". myLog::GetErrors());
I tried extending the PHPUnit_Framework_TestCase::assertThat function with my appended message, but it doesn't seem to have an effect on it. I know the extended PHPUnit_Framework_TestCase works because I have several helper functions (random string generation) in there as well that I use for testing.
Any other thoughts? Could it be a customer listener?
All of the assertions are static methods from PHPUnit_Framework_Assert and cannot be overridden by a subclass of TestCase. You can define your own assertions that call the originals with an amended message, however.
public static function assertTrue($value, $message='') {
PHPUnit_Framework_Assert::assertTrue($value, $message . myLog::GetErrors());
}
All failed tests call onNotSuccessfulTest() with the exception as the only parameter. You could override this method and in some cases add your log errors to the exception's message. Some of the PHPUnit exceptions provide a second description in addition to the error message contained in the exception.
public function onNotSuccessfulTest(Exception $e) {
if ($e instanceof PHPUnit_Framework_ExpectationFailedException) {
$e->setCustomMessage(implode(PHP_EOL,
array($e->getCustomMessage(), myLog::GetErrors())));
}
parent::onNotSuccessfulTest($e);
}
Update: As Gregory Lo noted in a comment below, setCustomMessage() and getCustomMessage() were removed in PHPUnit 3.6. :(
In recent PHPUnit Versions it is not necessary anymore.
When you specify the error parameter in an $this->assertXXXX() it preceeds PHPUnit's original message.
Screenshot: