Download the PHP package bovigo/callmap without Composer

On this page you can find all versions of the php package bovigo/callmap. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package callmap

bovigo/callmap

Allows to stub and mock method and function calls by applying a callmap. Compatible with any unit test framework.

Package status

Tests Coverage Status

Latest Stable Version

Installation

bovigo/callmap is distributed as Composer package. To install it as a development dependency of your package use the following command:

To install it as a runtime dependency for your package use the following command:

Requirements

bovigo/callmap requires at least PHP 8.2.

For argument verification one of the following packages is required:

The order specified here is also the one in which the verification logic will select the assertions to be used for argument verification. This means even if you run your tests with PHPUnit but bovigo/assert is present as well argument verification will be done with the latter.

Usage

Explore the tests to see how bovigo/callmap can be used. For the very eager, here's a code example which features almost all of the possibilities:

However, if you prefer text instead of code, read on.

Note: for the sake of brevity below it is assumed the used classes and functions are imported into the current namespace via

Specify return values for method invocations

As the first step, you need to get an instance of the class, interface or trait you want to specify return values for. To do this, bovigo/callmap provides two possibilities. The first one is to create a new instance where this instance is a proxy to the actual class:

This creates an instance where each method call is passed to the original class in case no return value was specified via the callmap. Also, it calls the constructor of the class to instantiate of. If the class doesn't have a constructor, or you create an instance of an interface or trait, the list of constructor arguments can be left away.

The other option is to create a complete stub:

Instances created that way don't forward method calls.

Ok, so we created an instance of the thing that we want to specify return values for, how to do that?

We simply pass a callmap to the returns() method. Now, if something calls $yourClass->aMethod(), the return value will always be 303. In the case of $yourClass->otherMethod(), the callable will be evaluated and its return value will be returned.

Please be aware that the array provided with the returns() method should contain all methods that should be stubbed. If you call this method a second time the complete callmap will be replaced:

As a result of this, $yourClass->aMethod() is not set any more to return 303.

Default return values

Depending on what is instantiated and how, there will be default return values for the case that no call mapping has been passed for a method which actually is called.

  1. Interfaces: Default return value is always null, except the return type declaration specifies the interface itself and is not optional, or the @return type hint in the doc comment specifies the short class name or the fully qualified class name of the interface itself or any other interface it extends. In that case the default return value will be the instance itself.

  2. Traits: When instantiated with NewInstance::of() the default return value will be the value a call to the according method returns.
    When instantiated with NewInstance::stub() and for abstract methods the default return value is null, except the @return type hint in the doc comment specifies $this or self.

  3. Classes: When instantiated with NewInstance::of() the default return value will be the value which is returned by the according method of the original class.
    When instantiated with NewInstance::stub() and for abstract methods the default return value is null, except the return type declaration specifies the class itself and is not optional, or the @return type hint in the doc comment specifies $this, self or static (the latter since release 6.2), the short class name or the fully qualified class name of the class or of a parent class or any interface the class implements. Exception to this: if the return type is \Traversable and the class implements this interface return value will be null.

Note: support for @return annotations in doc comments is deprecated and will be removed with release 9.0.0. Starting from 9.0.0 only explicit return type declarations will be supported.

Specify a series of return values

Sometimes a method gets called more than once and you need to specify different return values for each call.

This will return a different value on each invocation of $yourClass->aMethod() in the order of the specified return values. If the method is called more often than return values are specified, each subsequent call will return the default return value as if no call mapping has been specified.

I want to return a callable, but it is executed on method invocation

Because callables are executed when the method is invoked it is required to wrap them into another callable. To ease this, the wrap() function is provided:

The reason it is that way is that it is far more likely you want to calculate the return value with a callable instead of simply returning the callable as a result of the method call.

Let's throw an exception

Sometimes you don't need to specify a return value, but want the method to throw an exception on invocation. Of course you could do that by providing a callable in the callmap which throws the exception, but there's a more handy way available:

Now each call to this method will throw this exception. Since release 3.1.0 it is also possible to throw an \Error (basically, any \Throwable for that matter):

Of course this can be combined with a series of return values:

Here, the first invocation of $yourClass->aMethod() will return 303, whereas the second call will lead to the exception being thrown.

In case a method gets invoked more often than results are defined with onConsecutiveCalls() then it falls back to the default return value (see above).

Is there a way to access the passed arguments?

It might be useful to use the arguments passed to a method before returning a value. If you specify a callable this callable will receive all arguments passed to the method:

However, if a method has optional parameters the default value will not be passed as argument if it wasn't given in the actual method call. Only explicitly passed arguments will be forwarded to the callable.

Do I have to specify a closure or can I use an arbitrary callable?

You can:

How do I specify that an object returns itself?

Actually, you don't. bovigo/callmap is smart enough to detect when it should return the object instance instead of null when no call mapping for a method was provided. To achieve that, bovigo/callmap tries to detect the return type of a method from either from the return type hint or the method's doc comment. If the return type specified is the class or interface itself it will return the instance instead of null, except when the return type hint allows null.

If no return type is defined and the return type specified in the doc comment is one of $this, self, static (since release 6.2), the short class name or the fully qualified class name of the class or of a parent class or any interface the class implements, it will return the instance instead of null.

Exception to this: if the return type is \Traversable this doesn't apply, even if the class implements this interface.

Please note that @inheritDoc is not supported.

In case this leads to a false interpretation and the instance is returned when in fact it should not, you can always overrule that by explicitly stating a return value in the callmap.

Note: support for @return annotations in doc comments is deprecated and will be removed with release 9.0.0. Starting from 9.0.0 only explicit return type declarations will be supported.

Which methods can be used in the callmap?

Only non-static, non-final public and protected methods can be used.

In case you want to map a private, or a final, or a static method you are out of luck. Probably you should rethink your class design.

Oh, and of course you can't use all of this with a class which is declared as final.

What happens if a method specified in the callmap doesn't exist?

In case the callmap contains a method which doesn't exist or is not applicable for mapping (see above) returns() will throw an \InvalidArgumentException. This also prevents typos and wondering why something doesn't work as expected.

Verify method invocations

Sometimes it is required to ensure that a method was invoked a certain amount of times. In order to do that, bovigo/callmap provides the verify() function:

In case it was not called exactly once, this will throw a CallAmountViolation. Otherwise, it will simply return true.

Of course you can verify the call amount even if you didn't specify the method in the callmap.

Here is a list of methods that the instance returned by verify() offers for verifying the amount of method invocations:

In case the method to check doesn't exist or is not applicable for mapping (see above) all of those methods throw an \InvalidArgumentException. This also prevents typos and wondering why something doesn't work as expected.

By the way, if PHPUnit is available, CallAmountViolation will extend PHPUnit\Framework\ExpectationFailedException. In case it isn't available it will simply extend \Exception.

Verify passed arguments

Please note that for this feature a framework which provides assertions must be present. Please see the requirements section above for the list of currently supported assertion frameworks.

In some cases it is useful to verify that an instance received the correct arguments. You can do this with verify() as well:

This will verify that each of the expected arguments matches the actually received arguments of the first invocation of that method. In case you want to verify another invocation, we got you covered:

This applies verification to the arguments the method received on the third invocation.

There is also a shortcut to verify that the method didn't receive any arguments:

In case the method wasn't invoked (that much), a MissingInvocation exception will be thrown. In case the method received less arguments than expected, a ArgumentMismatch exception will be thrown. It will also be thrown when receivedNothing() detects that at least one argument was received.

Please not that each method has its own invocation count (whereas in PHPUnit the invocation count is for the whole mock object). Also, invocation count starts at 1 for the first invocation, not at 0.

If the verification succeeds, it will simply return true. In case the verification fails an exception will be thrown. Which exactly depends on the available assertion framework.

Verification details for bovigo/assert

Available since release 2.0.0.

Both reveived() and receivedOn() also accept any instance of bovigo\assert\predicate\Predicate:

In case a bare value is passed it is assumed that bovigo\assert\predicate\equals() is meant. Additionally, instances of PHPUnit\Framework\Constraint\Constraint are accepted as well as bovigo/assert knows how to handle those.

In case the verification fails an bovigo\assert\AssertionFailure will be thrown. In case PHPUnit is available as well this exception is also an instance of PHPUnit\Framework\ExpectationFailedException.

Verification details for PHPUnit

Both reveived() and receivedOn() also accept any instance of PHPUnit\Framework\Constraint\Constraint:

In case a bare value is passed it is assumed that PHPUnit\Framework\Constraint\IsEqual.

In case the verification fails an PPHPUnit\Framework\ExpectationFailedException will be thrown by the used PHPUnit\Framework\Constraint\Constraint.

Verification details for xp-framework/unittest

Available since release 1.1.0.

In case xp-framework/unittest is present, \util\Objects::equal() will be used.

In case the verification fails an \unittest\AssertionFailedError will be thrown.

Mocking injected functions

Available since release 3.1.0.

Sometimes it is necessary to mock a function. This can be cases like when PHP's native fsockopen() function is used. One way would be to redefine this function in the namespace where it is called, and let this redefinition decide what to do.

However, this approach is not as optimal, as most likely it is required to not just mock the function, but to also evaluate whether it was called and maybe if it was called with the correct arguments.

bovigo/callmap suggests to use function injection for this. Instead of hardcoding the usage of the fsockopen() function or even to introduce a new interface just for the sake of abstracting this function, why not inject the function as a callable?

Now a mocked callable can be generated with bovigo/callmap:

As with NewInstance::of() the callable generated with NewCallable::of() will call the original function when no return value is specified via the returns() method. In case the mocked function must not be called the callable can be generated with NewCallable::stub() instead:

As with a callmap for a method, several different invocation results can be set:

For the latter, since release 3.2.0 a shortcut is available:

It is also possible to verify function invocations, as can be done with method invocations:

Everything that applies to method verification can be applied to function verification, see above. The only difference is that the second parameter for verify() can be left away, as there is no method that must be named.


All versions of callmap with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
bovigo/assert Version ^8.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package bovigo/callmap contains the following files

Loading the files please wait ....