1

I have two tests files with tests that need to shadow the t() function in the Node Revision Delete project, one test file is placed in:

tests/src/Unit/Utility/TimeTest.php

And the other in:

tests/src/Unit/NodeRevisionDeleteTest.php

At this time I shadow the t() function with the same code at the end of each test file because the t() function is needed to run tests in both files.

namespace Drupal\node_revision_delete\Utility;

/**
 * Shadow t() system call.
 *
 * @param string $string
 *   A string containing the English text to translate.
 *
 * @return string
 *   The translated string.
 */
function t($string) {
  return $string;
}

When I run each test file all is working fine, but when I run all the project tests I get an error as I have declared the t() function twice:

PHP Fatal error: Cannot redeclare Drupal\node_revision_delete\Utility\t() (previously declared in /Users/adriancid/Sites/drupal84-test/modules/drupal.org/node_revision_delete/tests/src/Unit/NodeRevisionDeleteTest.php:357) in /Users/adriancid/Sites/drupal84-test/modules/drupal.org/node_revision_delete/tests/src/Unit/Utility/TimeTest.php on line 195

The only way that I found to make these works is to pass the tests that need the t() function from one test file to the other, but doing this I will have a mix of tests from diferent classes and I won't be able to use the @covers section in the test definition.

So, what is the correct way to shadow a core function used in two different tests files?

1 Answer 1

5

Wrap it in a !function_exists()

See core/tests/Drupal/Tests/Core/Render/Element/MachineNameTest.php for example:

<?php

namespace Drupal\Core\Render\Element;

if (!function_exists('t')) {

  function t($string, array $args = []) {
    return strtr($string, $args);
  }

}

That said, t() as a specific example is deprecated and should not be used in classes, use the StringTranslationTrait/service instead and you can actually inject it.

5
  • Hi @Berdir, thanks for your answer, I use the t() function because it is used in a static method in a Utility function. I tried your solution but it doesn't work, can you check the patch here? drupal.org/project/node_revision_delete/issues/… Commented Aug 8, 2018 at 14:15
  • Its weird, the test works on drupal.org but not in my local environment, I'm still getting the same error. Commented Aug 8, 2018 at 15:39
  • 1
    drupal.org runs tests through run-tests.sh, which spawns a separate process for each test. Sounds like your utility classs then maybe shouldn't be static because you have dependencies to services? unit-testability is one of the reasons you want to create services and use DI instead of static methods. You're fixing the wrong problem :)
    – Berdir
    Commented Aug 8, 2018 at 18:11
  • I don't have dependencies on services, you can check the code at cgit.drupalcode.org/node_revision_delete/tree/src/Utility/… I posted a question related to Utility class and Services on drupal.stackexchange.com/q/251111/28275 and it seems that I can keep my method as static, I don't know what do you think about this. Commented Aug 8, 2018 at 18:34
  • Yes, you do. t() is just a wrapper around creating a new TranslatableMarkup() object, which in turn uses the string_translation service. You have dependencies, they're just hidden behind a function.
    – Berdir
    Commented Aug 8, 2018 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.