Download the PHP package dancras/doubles without Composer

On this page you can find all versions of the php package dancras/doubles. 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 doubles

Doubles

Doubles is a php test doubles library with a goal to provide a simple, logical api and some syntactic sugar when writing unit tests. It is particularly suitable for the arrange-act-assert pattern of unit testing, although it doesn't intentionally impose any style. It has been designed with phpunit in mind, but has no dependencies and could have valid use cases with other testing frameworks. It is currently in the early stages of development and any feedback is very welcome.

Requires PHP 5.3+.

No changes to your unit testing framework are required for integration.

Copyright (c) 2012 Daniel Howlett

Dual licensed under the MIT and GPL licenses.

Feedback can be left at http://www.dancras.co.uk

Build Status

Installation with composer

To install from packagist, add the following to your composer.json:

{
    "minimum-stability": "dev",
    "require": {
        "dancras/doubles": "*"
    }
}

Don't forget to include vendor/autoload.php in your code.

Known issues

Reference

Add the following:

use Doubles\Doubles;

Full test doubles

Create test doubles with all methods of subject replaced:

$double = Doubles::fromClass('\MyClass');

$double = Doubles::fromInterface('\MyInterface');

Doubles will create the subject if it does not exist yet.

Partial test doubles

Methods of a partial test double are unaffected until they are stubbed, mocked or intercepted. They are created from an instance of the subject.

$subject = new \Doubles\Test\Dummy;

$double = Doubles::partial($subject);

It might be necessary to skip the constructor of a subject:

$subject = Doubles::noConstruct('\Doubles\Test\Dummy');

Spies

Provide access to the history of interactions with a test double, including unaffected methods of partial test doubles. A graph service test double might have the following actions performed on it:

$double->plot(0, 5);

$double->plot(2, 6);

$double->setLineColour('red');

$double->render();

We can interrogate the test double after the code is run:

$double->spy('plot')->args(0); // array(0, 5)

$double->spy('plot')->args(); // array(array(0, 5), array(2, 6))

$double->spy('plot')->findArgs(2, 6); // 1

$double->spy('plot')->arg(1, 0); // 2

$double->spy('plot')->callCount(); // 2

$double->callCount(); // 4

One Call

When a method is expecting one call we can avoid superfluous assertions by using the one call variant. Notice you can omit the call index when using the one call variant.

$double->spy('setLineColour')->oneCallArgs(); // array('red')

$double->spy('setLineColour')->oneCallArgs(0); // 'red'

A one call method will throw an exception if the method has not received exactly one call.

$double->spy('plot')->oneCallArgs(); // throws \Doubles\Core\FailureException

$double->spy('foo')->oneCallArgs(); // throws \Doubles\Core\FailureException

Call Order

Starts from one. Can be used to assert that methods are called in the expected order.

$double->spy('plot')->callOrder(0); // 1

$double->spy('plot')->callOrder(1); // 2

The one call variant also works for call order:

$double->spy('render')->oneCallOrder(0); // 4

The following code asserts that render is called last and only once:

$this->assertSame(
    $double->callCount(),
    $double->spy('render')->oneCallOrder(0)
); // pass

Shared Call Order

Occasionally you need to compare the call order between instances. The Doubles\Spy\CallCounter::shareNew() method distributes a shared call counter. Assume all objects in this example have been created as test doubles:

use Doubles\Spy\CallCounter;

CallCounter::shareNew($pizza, $waiter, $customer);

The following actions are incorrectly performed on our objects. Our impatient customer seems to be helping him or herself:

$pizza->cook();

$customer->eat($pizza);

$waiter->take($pizza);

Using the shared call order we can catch this error in our tests. The pizza must be cooked before the waiter takes it:

$this->assertGreaterThan(
    $pizza->spy('cook')->oneSharedCallOrder(),
    $waiter->spy('take')->sharedCallOrder(0)
); // pass

The waiter must take the pizza before the customer eats it:

$this->assertGreaterThan(
    $waiter->spy('take')->sharedCallOrder(0),
    $customer->spy('eat')->sharedCallOrder(0)
); // fail

Notice again the one call variant, ensuring our pizza is not burnt.

Stubs

$double->stub('foo', 'bar');

$double->foo(); // 'bar'

We can stub multiple methods at once, eg. to stub a fluent interface:

$double->stub('setX', 'setY', $double);

$double->setX(); // $double

$double->setY(); // $double

Stubs can also throw exceptions:

$double->stub('boom', new EndOfTheWorldException);

$double->boom(); // throws EndOfTheWorldException

To actually return an exception you need to use a mock.

Mocks

Mocking is the most versatile way to test a method but can be difficult to follow.

$myObject->mock('give', function ($methodName, $arguments) use (&$m, &$a) {
    $m = $methodName; // 'give'
    $a = $arguments; // array(1, 2, 3)
    return 'result';
});

$myObject->give(1, 2, 3); // 'result'

Performing assertions within the mock callback is not recommended. If your code fails to call the method, no assertions will be run and the test may pass.

If you are asserting within the mock, you may want to use a spy. Alternatively, using variables by reference will allow you to perform your assertions outside the closure.

Interceptors

Intercepting is an improved form of mocking available to partials, providing the instance of the partial subject to the callback.

$myObject->intercept('foo', function ($methodName, $arguments, $instance) use (&$m, &$a) {
    $m = $methodName; // 'foo'
    $a = $arguments; // array(1, 2, 3)
    return $instances->foo($a);
});

$myObject->give(1, 2, 3); // 'result'

Expectations

When you mock or stub a method it becomes expected. By default, calls to methods that are not expected have no repercussions.

$myObject->unknown(); // null

$myObject->setUnexpectedMethodCallback(function ($methodName, $arguments) {
    throw new Exception;
});

$myObject->unknown(); // throws Exception

Rapid Prototyping

By default, when using a test double for a defined type, an exception will be thrown if a method that doesn't exist on the original class or the test double API is called.

If the type doesn't exist then it is considered to be rapid prototyping (because having to define all your class signatures up front gets tedious). In this mode any methods can be used. When you define the class or interface, tests will fail until you complete it's signature.

I find this behaviour very effective, however if it is not desired functionality then rapid prototyping mode can be forced on, meaning methods outside the class or interface signature can be used freely.

\Doubles\Core\TestDouble::$isRapidPrototypingEnabled = true;

All versions of doubles with dependencies

PHP Build Version
Package Version
Requires php Version >=5.3.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 dancras/doubles contains the following files

Loading the files please wait ....