Testing with immutable PSR-7 objects and Prophecy

This page summarizes the projects mentioned and recommended in the original post on dev.to

Our great sponsors
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • WorkOS - The modern identity platform for B2B SaaS
  • SaaSHub - Software Alternatives and Reviews
  • Prophecy

    Highly opinionated mocking framework for PHP 5.3+

    Recently I have been working a lot with PSR-15 and PSR-18 and one of the characteristics of these recommendations is that it uses the immutable objects specified in PSR-7. Soon after we introduced PSR-18 in our codebase a colleague implemented a client including a unit test that was passing. And yet the code was failing when run in the browser. The cause of this was that the fact that RequestInterface objects are immutable by specification was overlooked. Due to the use of Prophecy and prophesized objects we were struggling to properly test it. Until another colleague introduced me to Argument::that() that is.

  • Mockery

    Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL).

    This works great if a method is tested that modifies and returns an object; we'll get an instance of that object and we are able to run all sorts of assertions on it. But what if this is not the case. What if we have a situation where a value object is passed as a parameter, some modifications are done and the value object is passed to another object. Something like the middleware from the example earlier. Some testing frameworks like Mockery offer spies to test these situations. When using Prophecy this situation can be handled using Argument::that():

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

  • phpunit-injector

    Injects services from a PSR-11 dependency injection container to PHPUnit test cases

    This unit test will fail when ran against the implementation from earlier. And in this situation a failing test is a good thing. But for this specific situation another "issue" has made it's way into the testcase; the unit test is now depending on the implementation that is being used for PSR-7. When working in a large codebase - like I currently am - one might have more than just a few usages of these interfaces and thus unit tests. Using the suggested approach, instantiating value objects instead of prophesizing, will lead to a large amount of object instantiations. And this will make switching to another implementation more work. Ideally this instantiating is centralized as much as possible. This is exactly why PSR-17 - HTTP Factories - was introduced. Typically dependencies - like these factories - are injected. For unit tests this is not feasible without plugins. My solution is a bit less fancy; a trait:

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts