We use Drupal 7 as our base CMS tool.
For one specific product, something like an ERP, we’ve created sort of a non-drupal layer, to keep our specific business code in.
It would be something like this:
-------------
| Business | -> This would be our business specific code layer
-------------
| Glue | -> This is where we connect with the basic Drupal API as we need
-------------
| Drupal | -> This is Drupal API
-------------
We have the concept of Repository
, which is a basic class that retrieves something from the database in the form of an Entity
or a ArrayObject
of Entities
.
This layer is connected to Drupal, since it needs access to the db_query() method, from the Drupal 7 API.
Our whole Business
layer is tested using PHPUnit
, with 100% coverage.
Now we are trying to test the Glue
layer as well, the unit of the Repositories
, their return values and parameters.
In order to do that, we came to the conclusion that we would need to mock the Drupal
database access API.
But to do that, what would be the correct or best approach?
- Wrap the
db_query
function fromDrupal
into a class that could be mocked in the tests? - Not test the
Repositories
at all?
4
Well, as in many cases the answer to your question starts with… “It depends.”
First, you should ask yourself “Is there any logic in the Repository / Glue layer?” I mean other than adapting to and from the D7 API. If the repositories for example have methods that offer a custom query language for you to find specific objects or set of objects, methods that do selecting and sorting these objects, than you probably wish to test the Repository.
The ideal way to do it would be as you suggested, with a Mock of an intermediary class to db_query(). But before you jump into this and start coding take a minute and think about your repositories. Maybe it is acceptable to test it with a real database specially prepared with objects you know and can control for testing purposes. I find that most of the time, these very rarely changing parts of your design can be tested at this higher level. The test will run a little bit slower, but maybe you can get away with running them together with the functional / integration tests you may have on your system. After all, the whole “glue” thing is for integration.
You may also speed up the tests with databases by creating the databases in RAM only, or on a mount point serving as ram-disk.
2
Based on your additional comments, I personally would not bother mocking any class up to simulate the Drupal API. It sounds as if you’ve designed Glue to abstract the Drupal API a bit from the Business layer, to make it easier to work with.
To provide reasonable test coverage for Glue without going overboard, I might suggest doing some basic black-box unit tests against the Drupal API calls you intend to use to ensure they are working as expected. You’ll have confidence that the Drupal API is doing what is expected, and that you’re integrating against a working API. Then you should test Glue and the Drupal API together. Once you’ve defined your tests and you execute them to your satisfaction, I would consider Glue tested sufficiently.
Under this approach, since you’re not intending to use Glue with any other API other than Drupal, I think you’ll have tested Glue adequately without burning extra cycles creating more work for yourself than needed.