{"action":"created","issue":{"url":"https://api.github.com/repos/padraic/mockery/issues/594","repository_url":"https://api.github.com/repos/padraic/mockery","labels_url":"https://api.github.com/repos/padraic/mockery/issues/594/labels{/name}","comments_url":"https://api.github.com/repos/padraic/mockery/issues/594/comments","events_url":"https://api.github.com/repos/padraic/mockery/issues/594/events","html_url":"https://github.com/padraic/mockery/issues/594","id":153048764,"number":594,"title":"Mocking demeter chain method erases class type","user":{"login":"aarantes-engage","id":19190475,"avatar_url":"https://avatars.githubusercontent.com/u/19190475?v=3","gravatar_id":"","url":"https://api.github.com/users/aarantes-engage","html_url":"https://github.com/aarantes-engage","followers_url":"https://api.github.com/users/aarantes-engage/followers","following_url":"https://api.github.com/users/aarantes-engage/following{/other_user}","gists_url":"https://api.github.com/users/aarantes-engage/gists{/gist_id}","starred_url":"https://api.github.com/users/aarantes-engage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aarantes-engage/subscriptions","organizations_url":"https://api.github.com/users/aarantes-engage/orgs","repos_url":"https://api.github.com/users/aarantes-engage/repos","events_url":"https://api.github.com/users/aarantes-engage/events{/privacy}","received_events_url":"https://api.github.com/users/aarantes-engage/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-05-04T15:56:24Z","updated_at":"2016-05-04T20:43:26Z","closed_at":null,"body":"I'm trying to mock a `Car` object with a demeter chain for honking the horn (eg. `$car->horn()->honk()`). \r\n\r\nFor some reason `$mockCar instanceof Car` yields `true` for\r\n\r\n`$mockCar = Mockery::mock(Car::class)->shouldRequire('horn')->mock();`\r\n\r\nbut `false` for\r\n\r\n`$mockCar = Mockery::mock(Car::class)->shouldRequire('horn->honk')->mock();`\r\n\r\nThis makes it difficult to pass mock objects to functions such as `function driveCar(Car $car) {...}`\r\n\r\nIt seems to me that the methods that are mocked on an object should not affect the type of the object itself. If I add a method bar() to class Foo, that should not change its type from Foo to NotFoo. \r\n\r\nThe functionality works correctly when the horn() method is mocked separately to return an instance of Horn instead of using demeter chains in shouldRequire().\r\n\r\n\r\nSome sample code from a test suite illustrates the problem:\r\n\r\n\r\n\t<?php namespace Unit\\Automotive;\r\n\r\n\tclass Car {\r\n\t\t/* ... */\r\n\t}\r\n\r\n\tfunction driveCar(Car $car) {\r\n\t    /*\r\n\t       ...\r\n\t       $car->horn->honk();\r\n\t       ...\r\n\t    */\r\n\t}\r\n\r\n\tclass AutotiveTest extends TestCase\r\n\t{\r\n\r\n\t\tpublic function testCar() {\r\n\r\n\t\t\t// define mock objects\r\n\t\t\t$mockCar = Mockery::mock(Car::class)\r\n\t\t\t\t->shouldReceive('horn')\r\n\t\t\t\t->mock();\r\n\r\n\t\t\t$badMockCar = Mockery::mock(Car::class)\r\n\t\t\t\t->shouldReceive('horn->honk')\r\n\t\t\t\t->mock();\r\n\r\n\t\t\t// debug information\r\n\t\t\tprintf(\"mockCar is car: %s, get_class()=%s\\n\",\r\n\t\t\t\t$mockCar instanceof Car ? 'true' : 'false',\r\n\t\t\t\tget_class($mockCar));\r\n\r\n\t\t\tprintf(\"badMockCar is car: %s get_class()=%s\\n\",\r\n\t\t\t\t$badMockCar instanceof Car ? 'true' : 'false',\r\n\t\t\t    get_class($badMockCar));\r\n\r\n\t\t\t// this is ok, $mockCar is a Car\r\n\t\t\tdriveCar($mockCar);\r\n\r\n\t\t\t// this throws an exception because $badMockCar is not a Car\r\n\t\t\tdriveCar($badMockCar);\r\n\r\n\t\t}\r\n\t}\r\n\r\n\r\nThis outputs:\r\n\r\n\tmockCar is car: true, get_class()=Mockery_0_Unit_Automotive_Car\r\n\tbadMockCar is car: false get_class()=Mockery_1__demeter_horn\r\n\r\n\tThere was 1 error:\r\n\r\n\t1) Unit\\Automotive\\AutotiveTest::testCar\r\n\tErrorException: Argument 1 passed to Unit\\Automotive\\driveCar() must be an instance of Unit\\Automotive\\Car, instance of Mockery_1__demeter_horn given, called in /var/www/*redacted*/tests/Unit/Automotive/AutomotiveTest.php on line 46 and defined\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/padraic/mockery/issues/comments/216996794","html_url":"https://github.com/padraic/mockery/issues/594#issuecomment-216996794","issue_url":"https://api.github.com/repos/padraic/mockery/issues/594","id":216996794,"user":{"login":"aarantes-engage","id":19190475,"avatar_url":"https://avatars.githubusercontent.com/u/19190475?v=3","gravatar_id":"","url":"https://api.github.com/users/aarantes-engage","html_url":"https://github.com/aarantes-engage","followers_url":"https://api.github.com/users/aarantes-engage/followers","following_url":"https://api.github.com/users/aarantes-engage/following{/other_user}","gists_url":"https://api.github.com/users/aarantes-engage/gists{/gist_id}","starred_url":"https://api.github.com/users/aarantes-engage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aarantes-engage/subscriptions","organizations_url":"https://api.github.com/users/aarantes-engage/orgs","repos_url":"https://api.github.com/users/aarantes-engage/repos","events_url":"https://api.github.com/users/aarantes-engage/events{/privacy}","received_events_url":"https://api.github.com/users/aarantes-engage/received_events","type":"User","site_admin":false},"created_at":"2016-05-04T20:43:26Z","updated_at":"2016-05-04T20:43:26Z","body":"That makes sense. \r\n\r\n`Mockery::mock(Car::class)` returns an object of type `Car` and \r\n`Mockery::mock(Car::class)->shouldReceive('horn->honk')` returns an object of type `horn`.\r\n\r\nWould it be possible to add a line to the documentation at https://github.com/padraic/mockery/blob/master/docs/reference/demeter_chains.rst to remind people not to chain both expressions together?"}}