Mock service on functional test

New topics about Symfony 2 should go here

Moderators: dcobalt, tiagojsag

Mock service on functional test

Postby fernandonn » Fri Apr 06, 2012 8:29 pm

Hi,

(added test case on 3rd response)

I am testing a controller that uses a service. Some test should not invoke de service, but use a mock instead.
Unfortunately, it does not work always... the real service was called instead. After adding some echos on the test code I discovered that.

If I execute a test like this:

$this->client->getContainer()->set('myservice', $stub);
echo "\n" . get_class( $this->client->getContainer()->get('myservice') );
$this->sendForm();
echo "\n" . get_class( $this->client->getContainer()->get('myservice') );

The console says:

Mock_MyService_11617d3f
fernandonn\MyServiceBundle\Service\MyService

I interpret that before sendForm call, the service is my mock, but after sendForm it was reverted to the original service.

In fact.. inside the controller, I added a echo and the result was that it was using always fernandonn\MyServiceBundle\Service\MyService when it was called using sendForm. Others tests that do not call sendForm (just render a page without post) do not have the same problem.

How can I specify the mock service to use on a test in this case?
Thanks in advance.
Last edited by fernandonn on Sat Apr 07, 2012 7:44 pm, edited 1 time in total.
User avatar
fernandonn
Junior Member
 
Posts: 20
Joined: Mon Oct 24, 2011 6:37 am
Location: Buenos Aires

Re: Mock service on functional test

Postby blogsh » Sat Apr 07, 2012 12:17 pm

Have you read about the service container and DI in Symfony? The framework doesn't use a "global" service registry (although you can), but Dependency Injection instead. This means that the services are passed to their dependent services at startup directly (they don't rely on the container).

Where does the method "sendForm" come from? If you provide more information we can find a way how you can mock your service :)
blogsh
Faithful Member
 
Posts: 501
Joined: Thu Mar 03, 2011 9:35 pm
Location: Germany

Re: Mock service on functional test

Postby fernandonn » Sat Apr 07, 2012 7:43 pm

Sorry about my previous post. It was a old project that i just resumed and I forgot that sendForm was an auxiliary method that I created for my tests.
Anyway as an example is the best documentation, I'll post here the bare minimum to reproduce the problem.

First. I have a Service that just returns a string.

Code: Select all
namespace TestVendor\WebTestBundle\Service;

class MyService {
   public function testMethod() { return "Real service"; }
}


Then, I have a controller that uses this Service, through dependency injection, after a form is submitted. Then prints on screen the string that the service returned.

Code: Select all
namespace TestVendor\WebTestBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DefaultController extends Controller
{
    /**
     * @Route("/")
     * @Template()
     */
   public function indexAction(Request $request) {
      if ($request->getMethod() == 'POST') {
         $service = $this->get("myservice");
         $testingValue = $service->testMethod();
         
         return new Response( $testingValue );
      }
      return array();      
   }
}


I have configured the service at bundle level using services.yml...

Code: Select all
services:
    myservice:
        class:  TestVendor\WebTestBundle\Service\MyService


I have a very simple view, just a form with a submit button

Code: Select all
<form  method="post" action="">
   <input type="submit" id="submit" value="submit" />
</form>


And now, the important bit.. a test case that fails (when I expected it to work)
The test try to replace the service with a stub service that return another text and then asserts for that text.

Code: Select all
<?php

namespace TestVendor\WebTestBundle\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DefaultControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient();

        // mock the service
        $stub = $this->getMock('TestVendor\WebTestBundle\Service\MyService');
        $stub->expects($this->any())
             ->method('testMethod')
             ->will( $this->returnValue("Mock Service") );
        $client->getContainer()->set('myservice', $stub);
       
        $crawler = $client->request('GET', '/test/');

        // I also tried changing the container here, with the same result.

        $form = $crawler->selectButton("submit")->form();
        $crawler = $client->submit($form, array());
       
        $this->assertTrue($crawler->filter('html:contains("Mock service")')->count() > 0);
    }
}


It is just a simplified version of my actual problem, but I believe that is ok as an example.

I do not want to change services.yml to inject another service, when running on test environment, because I have many tests like this, some uses the real service, other need to use mocks with slightly different behavior.

The problem is with Submit method, if I tried something similar, but using request, it works ok.

Thank in advance.
Sorry about my english :(
User avatar
fernandonn
Junior Member
 
Posts: 20
Joined: Mon Oct 24, 2011 6:37 am
Location: Buenos Aires

Re: Mock service on functional test

Postby rpwalega » Fri Mar 15, 2013 9:43 pm

I have run into the exact same issue. What was your solution?

Ryan
rpwalega
Junior Member
 
Posts: 2
Joined: Fri Mar 15, 2013 9:38 pm

Re: Mock service on functional test

Postby fernandonn » Sat Mar 16, 2013 4:39 pm

As was an unimportant project, I had continued without test until I forgot about the project because boredom and other things to do.
But I didn't find a solution. My advice, ask again the same question on google groups, it seems more alive than the forums. (or at least it was last years)
User avatar
fernandonn
Junior Member
 
Posts: 20
Joined: Mon Oct 24, 2011 6:37 am
Location: Buenos Aires


Return to General Symfony 2 discussion

Who is online

Users browsing this forum: No registered users and 3 guests

cron