{"action":"created","issue":{"url":"https://api.github.com/repos/phpspec/phpspec/issues/810","labels_url":"https://api.github.com/repos/phpspec/phpspec/issues/810/labels{/name}","comments_url":"https://api.github.com/repos/phpspec/phpspec/issues/810/comments","events_url":"https://api.github.com/repos/phpspec/phpspec/issues/810/events","html_url":"https://github.com/phpspec/phpspec/issues/810","id":118895552,"number":810,"title":"Discussion: Correct way for testing a method that uses a named constructor?","user":{"login":"javierseixas","id":953900,"avatar_url":"https://avatars.githubusercontent.com/u/953900?v=3","gravatar_id":"","url":"https://api.github.com/users/javierseixas","html_url":"https://github.com/javierseixas","followers_url":"https://api.github.com/users/javierseixas/followers","following_url":"https://api.github.com/users/javierseixas/following{/other_user}","gists_url":"https://api.github.com/users/javierseixas/gists{/gist_id}","starred_url":"https://api.github.com/users/javierseixas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/javierseixas/subscriptions","organizations_url":"https://api.github.com/users/javierseixas/orgs","repos_url":"https://api.github.com/users/javierseixas/repos","events_url":"https://api.github.com/users/javierseixas/events{/privacy}","received_events_url":"https://api.github.com/users/javierseixas/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-11-25T18:22:40Z","updated_at":"2015-11-26T10:26:59Z","closed_at":null,"body":"Hi everybody,\r\nI know that phpspec guides through a good code design, and instantiating objects inside methods (instead of using dependecy injection) could mean some code smell, but I'm facing some doubts when working with [named constructors](http://verraes.net/2014/06/named-constructors-in-php/). I have the following classes:\r\n\r\n```php\r\nclass User\r\n{\r\n    ...\r\n    private function __construct($id, $name) { \r\n        $this->id = $id;\r\n        $this->name = $name;\r\n    }\r\n\r\n    public static function named($name) { \r\n        return new self(\r\n            Uuid::uuid4()->toString(), \r\n            $name\r\n        );\r\n    }\r\n}\r\n\r\nclass SignUpHandler\r\n{\r\n    ...\r\n    public function handle ($command)\r\n    {\r\n        // $command is just a DTO with an attribute $name\r\n        $user = User::name($command->name());\r\n        $this->myInjectedUserRepository->add($user);\r\n    }\r\n}\r\n```\r\n\r\nAnd I'd like to test my `SignUpHandler` with the following spec:\r\n\r\n```php\r\nClass SignUpHandlerSpec\r\n{\r\n    public function it_should_add_a_user(CreateUser $command, UserRepositoryInterface $userRepository)\r\n    {\r\n        $name = \"javier\";\r\n        $command->name()->willReturn($name);\r\n\r\n        $user= User::named($name);\r\n\r\n        $userRepository->add($user)->shouldBeCalled();\r\n\r\n        $this->handle($command);\r\n}\r\n```\r\n\r\nWhen I run the spec it fails cos I'm generating a new `uuid` with each instance, so the attribute `$id` in the expected `$user` I'm generating in the spec, mismatch the created one generated during the method process.\r\n\r\nThere is any way to make it pass? Any better way to test the `handle` method or any better approach to test methods with named constructors?\r\n\r\nThanks for any help :)"},"comment":{"url":"https://api.github.com/repos/phpspec/phpspec/issues/comments/159870468","html_url":"https://github.com/phpspec/phpspec/issues/810#issuecomment-159870468","issue_url":"https://api.github.com/repos/phpspec/phpspec/issues/810","id":159870468,"user":{"login":"jon-acker","id":956800,"avatar_url":"https://avatars.githubusercontent.com/u/956800?v=3","gravatar_id":"","url":"https://api.github.com/users/jon-acker","html_url":"https://github.com/jon-acker","followers_url":"https://api.github.com/users/jon-acker/followers","following_url":"https://api.github.com/users/jon-acker/following{/other_user}","gists_url":"https://api.github.com/users/jon-acker/gists{/gist_id}","starred_url":"https://api.github.com/users/jon-acker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jon-acker/subscriptions","organizations_url":"https://api.github.com/users/jon-acker/orgs","repos_url":"https://api.github.com/users/jon-acker/repos","events_url":"https://api.github.com/users/jon-acker/events{/privacy}","received_events_url":"https://api.github.com/users/jon-acker/received_events","type":"User","site_admin":false},"created_at":"2015-11-26T10:26:58Z","updated_at":"2015-11-26T10:26:58Z","body":"Is the users name never accessed? Often you'd have something like a __toString() method on the User class, in which case you could have partially matched the two $user objects using\r\n```php\r\n$userRepository->add(Argument::which('__toString', $name)->shouldBeCalled();\r\n```\r\nSince you're basically want to confirm that add() was called with a User with a specific name. \r\n\r\nAs you pointed out, since the UUID is generated on construction, there's no point in matching the two $user objects completely. If you just want to check that an object of the same type was passed, you could match using Argument::type('User')\r\n\r\nI believe it should be possible to use a combination of the custom matcher Argument::that(callback) with Reflection to check that the passed argument matches certain criteria though I've not tried this."}}