Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot handle DateTime dummies #454

Open
elvetemedve opened this issue Dec 6, 2019 · 0 comments
Open

Cannot handle DateTime dummies #454

elvetemedve opened this issue Dec 6, 2019 · 0 comments

Comments

@elvetemedve
Copy link
Contributor

Summary

When you want to use \DateTime object in PHPSpec tests as dummy object, then the test fails with the following error message:

err:Error("Call to a member function sub() on null")

The Problem

Let's suppose we have two classes Subject and Collaborator and we are writing spec for the former.
Source code looks like this:

<?php
// spec/SubjectSpec.php

namespace spec;

use PhpSpec\ObjectBehavior;
use Subject;

class SubjectSpec extends ObjectBehavior
{
    function it_can_handle_date_time_dummies(\DateTime $date, \Collaborator $c)
    {
	$this->beConstructedWith($c);

	$c->takeADate($date)->willReturn(true);

        $this->doSomething($date)->shouldReturn(true);
    }
}
<?php
// src/Subject.php

class Subject
{
    private $c;

    public function __construct(Collaborator $c)
    {
        $this->c = $c;
    }

    public function doSomething(\DateTime $date)
    {
    	return $this->c->takeADate($date);
    }
}
<?php
// src/Collaborator.php

interface Collaborator
{
    public function takeADate(\DateTime $date);
}

composer.json

{
    "name": "gbuza/spec-test",
    "authors": [
        {
            "name": "Géza Búza",
            "email": "bghome@gmail.com"
        }
    ],
    "require": {
        "phpspec/phpspec": "^6.1"
    },
    "autoload": {
        "psr-0": {
            "": "src"
        }
    }
}

Finally execute the tests: vendor/bin/phpspec run

Actual Result

Subject                                                                         
  10  - it can handle date time dummies
      exception [err:Error("Call to a member function sub() on null")] has been thrown.

                                      100%                                       1
1 specs
1 example (1 broken)

Expected Result

1 specs
1 example (1 passed)

Explanation

Prophecy uses the DateTimeComparator class from sebastian/comparator package from the ExactValueToken class in order to compare the actual date argument with the argument of the promise object. That worked fine before 2.1.1 or earlier versions. But in 2.1.2 methods of the \DateTime class are chained like $expected->setTimezone()->sub(). Since $expected is not a real \DateTime object, but actually a dummy test double, all of the methods will return null by definition. Therefore $expected->setTimezone() becomes null, that's why sub() cannot be called on that.

Since our compared object is not a real \DateTime, it should not be compared by the DateTimeComparator. The condition to support an object is to check the inheritance chain, it will be accepted for comparison which is fine when the real \DateTime class is extended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant