6

Generally a module file contains hooks and doesn't have any class nor namespaces. What I have studied so far is that PHP Unit testing is possible only when the code is contained in classes.

Can I write unit tests for module files?

1

1 Answer 1

5

Unit-testing procedural code

In principle, you can unit test procedural code just as easily as code that is in a class, but you can't really mock it. Therefore, whether your tested code is in a class doesn't matter so much as whether its dependencies are.

Even though procedural code cannot use dependency injection and has to access services via \Drupal::service(), you can put your mocks into a custom container and call \Drupal::setContainer():

$container = new ContainerBuilder();
// ... insert mocked services
\Drupal::setContainer($container);

That means if you call only class code like \Drupal::logger() or \Drupal\user\Entity\User::load() or even \Drupal::database(), you should be able to mock everything, load your .module file, then call all of the hooks and check that they return the correct values.

But if your code references procedural core constants or functions (eg REQUEST_TIME, db_query(), drupal_set_message(), watchdog_exception(), file_*(), user_load()) then those .inc/.module files must be included as well, along with any files used by that code. You'll quickly run into problems that way, as that code will assume it's running in a full Drupal instance. To test such code, a kernel test or functional (ie browser) test will likely be required.

Unit-testing Hooks

With hooks, there is an extra caveat for unit-testing: You are declaring a function that you expect to be called from elsewhere, and which often doesn't do much other than altering and returning arrays.

You can test that as a unit, but because the contract of that code is so vaguely defined, it generally won't tell you much. Most of the errors in such code will only be revealed by testing the results in a functional test.

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.