I've got a form class, and I'm injecting my custom functionality class into it via constructor. That class is added to the container via the services.yml file defined in my custom module.

I'd like to test that the form is functioning correctly, but for testing purposes I'd like to replace the class that's injected into the form with a fake one.

Both real and fake classes implement the same interface. The form is working with that interface.

My test file:

<?php
/**
 * @file
 * Contains \Drupal\my_module\Tests\FormTest.
 */

namespace Drupal\my_module\Tests;


use Drupal\my_module\Tests\Fake\FakeClass;
use Drupal\simpletest\WebTestBase;

class FormTest extends WebTestBase
{

    public static $modules = [
        'my_module',
    ];

    public function setUp()
    {
        parent::setUp();

        $fake = new FakeClass();

        $this->container->set('my_module.real_class', $fake);

        // $this->container->get('my_module.real_class') returns a FakeClass object.
    }

    public function testFormWorks()
    {
        $this->drupalGet('my-form');
        $this->drupalPostForm(NULL, [], 'Submit');
        $this->assertRaw('Form is working.');
    }

}

When I'm running the test, the real class is being used, which is not the desired test behaviour.

The issue is not specific to forms. Same thing happens in page controllers.

Comments

mkudenko created an issue. See original summary.

dawehner’s picture

Category: Bug report » Support request

I'm sorry but this is not a bug. Container->set() changes the container which is currently active. When you do a drupalPostForm you execute an actual HTTP request.
When you want to change the used container write a module and provide a service modified, see https://api.drupal.org/api/drupal/core%21core.api.php/group/container/8

mkudenko’s picture

Thank you, @dawehner. So if I understand correctly, I need to create a custom module that overrides the original service, and enable that module during tests. Is that correct?

mkudenko’s picture

dawehner’s picture

Status: Active » Fixed

Cool, thank you for posting your solution.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.