{"tag":"global function","articles":{"projects\/avris-functionmock":{"key":"projects\/avris-functionmock","type":"article","published":true,"meta":{"createdAt":"2017-12-21T10:18:21+01:00","publishedAt":"2017-12-21T10:16:00+01:00","group":"mocks","links":[{"icon":"brands gitlab","colour":"primary","url":"https:\/\/gitlab.com\/Avris\/FunctionMock","displayUrl":null}],"category":"projects","subcategory":null,"slug":"avris-functionmock"},"content":{"en":{"slug":"avris-functionmock","title":"Avris FunctionMock","intro":"\u003Cfigure\u003E\n                \u003Cnoscript\u003E\n                    \u003Cimg src=\u0022https:\/\/avris.it\/image\/avris-function-mock_small.png\u0022 alt=\u0022Avris FunctionMock\u0022 class=\u0022border-bottom\u0022 width=\u0022480\u0022 height=\u0022320\u0022\u003E                \n                \u003C\/noscript\u003E\n                \u003Cspan class=\u0022hide-noscript\u0022\u003E\u003Cimg src=\u0022data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAYCAYAAACSuF9OAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAHpklEQVRIiX2X269dVRXGf+My59p7n7PPpZfTlkJLAVFStZFIJCFKIQEhBhM0atAE9UEfMD74J\/jumw9G47M+GV8QE41GIIFEwXgBRCLYAgVKS9tz2\/vsvdacw4e1W4waZ9ZcayVrXr75fXPM8S05duPJiFIRgqgVomLu1FIIAhXB1TBVkjvz+YxaK0RABAKICEJfRAQRAYKrJSIWtV57EhURUBHMHROhaYZ4hBARlFqQAAFKKQj9wKraAxWFWkmqdIsJEFm041p7EQBBVd6fXK6+C1ELokbE+\/0MIamhteBXOwhKUIkADUG0n4wQVB0QulIxBEUIUUx1wUa\/EKT\/trgWN8PdmM9bRCCiX6CIoou+poqbkVTxEIVaFgT3jBCBhKBquCkmgonipkhUaq3UWvoB3PvV14qqXZNKRYhaCYLVtTWuXLoMVAhBHKIWVAUCzJRkRvKrgARQgbpgS0BEFzIYimJmZEuMmgaiYzKd0rjTJCd7otZKKR1dKSD0+6VWAI4c2mC2vQPUnrQIVPMClGLaS5xNcdFERIuEgVT02iYV1Kyn1hIqioqh4iw1S6wPV7m8s4mGEiVoPKGeIQohQte1PUMCx48d450zryMSSICpIASQEImFZEoyxTVlumARMXY1VkC1Z0cNUyO7ky2hGCKJJidOHFxmd7LDrG05dHiD+XTCztY2JkJ2pUblrvvv5tWXXmYlNwTRRxag2ouiCiKQTMlueGhC0kIuhBpgoqgaKoqb42pkz7gIyZwkiaQN+\/at8rmvfYF962v87me\/5I2zb2DNMsn7aBqvLnPXvXfz4pPPsDYYAoWI6MGooAJmgmnPmrvg5AbpnFpjoS+AImqoOSKGm6OacLNFTZx+8JM88q0v8cpzf+Px7\/+UROHWI9cRtbK9u4Nn4yvf\/Q7P\/fwJrl9ZYV5aanRElF46XURX6vdQToopuAyWqG1Bau3PoQDEEHHUEskcVSOZM0iZkTtff+zzfPrh0+xc3uaJHz5O1iHrowE333Idu5sX2Zzsce+3v0xSoZ59kw8d2WBnOmGvm1NqR6ktaCW5YSa4K8mFlAyX0Qoy76BUAvo9giKSUDHEE1mdQUqMUuKRR+\/j0w+fBuAvT79AomG8PGZ51LB9acrxj3+U+x+6Cx80PPu9H7NxYBWNls2toOsSJXpAIRXVIGXHXUhJ8Sy4DMeQOyggoRCKoCAOmjB1kjk5JU6dOsFnv3jPtZSwdX6H\/YcOcvT4BsdP3sANt9\/E0oEVIoI3fvUUS8NMqcsMmo7cVJBKjZaumxO1RQ1UA3MjN44nwRmvQleIkB5M9NFlOK4JxZHFAfjoNx+8djIDPPCN+\/jPEhGce+p55hcucvDG\/cw2M+3uFVa0RawiFtTaUrsZQoeaYK6knPGmwXU8JhX6PIPioSSMLE4OI6uRUW4\/dYyjR\/f9F4B\/L7UUXv31H9h+5VUGS8pgdcTB266n21xi621BZY7QgmSiJERqH2HJsZyxZoiP18aUAiwYMgQPZyDGAGWA0VThzk\/c8n\/B7FzY5KVfPMP8vQsMG0ChnU6YvNfiMme02lDb0p89BioJWcil7lgeoM0QP7xvSNcFtUANRUNRjBRCwhiE0hTh1psO\/E8g060Jf3\/6Bc798WWytAwHtU8dFaKFOjNolDxUIikmsZApoaZYymhukNRAHuIf3miY7LXMZ4V5VymlUmpFQpCoWBFMhAPro2sgdnemnH3lHGf+\/BrnXvwnTbSMvBCp4FSyVkIDLGDe50pJQfLATTATNCUkDyAZ5Ay5AR\/gD62\/xe5eZWenZWu3stMF2zOYzGGvhXknlA5+9IOfMN2dcuXiFruXtsilkCgkKgOtDK1jKQUrg8p8VGEcpBAG1tsMKS3qgWXDatC2hjGmnRk6SGxeHtEyQE6fPBArg8TeXm+V3DIhTsUJSRScqpmNw9dx\/uJFutI7AVejaRrWxsvMJlOyCY3C+nJmnIPVNOfIeuHEiXWo27z+9hV2plNKblm77ihP\/ub3nHl7xsqgsrExZtYGz760iz93rqIpEFUsGd4kRA3PDZ4ylhpUjdP3fIr5Sy9zcH0N1IlQjmwc4sKFyxxcX8VDmE+mnPzgCRoRdi+8yygHZd8Yn13iUPc611vH2lLHradG3HPTMS68vcV4CC4dB++8j8lff4vc8dXHolleoaswWBrjqUHVEXOSJ0QMAa7fv8YwJdZGDRcvbTNKjtTKbDrjwHjEZHePaDuWkhN7Mw6vLjFSWM7KQAvtlQtkq6yOKredXKNZgteef43xUGi8Y3joEHllFS8YO5MpWGK+vY3ILqC9F4regKsol997FykVSkVqpe7tQS1kM6QEEoHVQqL3xqOUGSdn7M5qkxglwbUwyrCz13LHR1Z487JSL3WsDGF85S0+8MDH8Mtn\/8G8bVHP1FLxZgjv\/0MggKeEqiIRRA00egBaK9J11wx+bWe4GFfOv84gD3ARVpdX2L+yhkdlMtlifWXMn1523jk75PzmHmfe22OYg0bnfKZ7Ezlw821RS6Gbz6ntjLQ0RkIo8z00NX06qB2eBwC95wa0BoogcdVD915cIxAqJoKr4AJKJZuhGnRdi1DYGDurA+PStLe5jcOdx+FfEghCLeMqGgkAAAAASUVORK5CYII=\u0022 data-src=\u0022https:\/\/avris.it\/image\/avris-function-mock_small.png\u0022 alt=\u0022Avris FunctionMock\u0022 class=\u0022border-bottom\u0022 width=\u0022480\u0022 height=\u0022320\u0022\u003E\u003C\/span\u003E\n                \n            \u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EFunctionMock is a simple and elegant way to mock away system\/global functions in your tests.\u003C\/p\u003E\u003Csvg xmlns=\u0022http:\/\/www.w3.org\/2000\/svg\u0022 style=\u0022display: none;\u0022\u003E\u003C\/svg\u003E","content":"\u003Cfigure\u003E\n                \u003Cnoscript\u003E\n                    \u003Cimg src=\u0022https:\/\/avris.it\/image\/avris-function-mock_big.png\u0022 alt=\u0022Avris FunctionMock\u0022 class=\u0022border\u0022 width=\u0022900\u0022 height=\u0022600\u0022\u003E                \n                \u003C\/noscript\u003E\n                \u003Cspan class=\u0022hide-noscript\u0022\u003E\u003Cimg src=\u0022data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAYCAYAAACSuF9OAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAHpklEQVRIiX2X269dVRXGf+My59p7n7PPpZfTlkJLAVFStZFIJCFKIQEhBhM0atAE9UEfMD74J\/jumw9G47M+GV8QE41GIIFEwXgBRCLYAgVKS9tz2\/vsvdacw4e1W4waZ9ZcayVrXr75fXPM8S05duPJiFIRgqgVomLu1FIIAhXB1TBVkjvz+YxaK0RABAKICEJfRAQRAYKrJSIWtV57EhURUBHMHROhaYZ4hBARlFqQAAFKKQj9wKraAxWFWkmqdIsJEFm041p7EQBBVd6fXK6+C1ELokbE+\/0MIamhteBXOwhKUIkADUG0n4wQVB0QulIxBEUIUUx1wUa\/EKT\/trgWN8PdmM9bRCCiX6CIoou+poqbkVTxEIVaFgT3jBCBhKBquCkmgonipkhUaq3UWvoB3PvV14qqXZNKRYhaCYLVtTWuXLoMVAhBHKIWVAUCzJRkRvKrgARQgbpgS0BEFzIYimJmZEuMmgaiYzKd0rjTJCd7otZKKR1dKSD0+6VWAI4c2mC2vQPUnrQIVPMClGLaS5xNcdFERIuEgVT02iYV1Kyn1hIqioqh4iw1S6wPV7m8s4mGEiVoPKGeIQohQte1PUMCx48d450zryMSSICpIASQEImFZEoyxTVlumARMXY1VkC1Z0cNUyO7ky2hGCKJJidOHFxmd7LDrG05dHiD+XTCztY2JkJ2pUblrvvv5tWXXmYlNwTRRxag2ouiCiKQTMlueGhC0kIuhBpgoqgaKoqb42pkz7gIyZwkiaQN+\/at8rmvfYF962v87me\/5I2zb2DNMsn7aBqvLnPXvXfz4pPPsDYYAoWI6MGooAJmgmnPmrvg5AbpnFpjoS+AImqoOSKGm6OacLNFTZx+8JM88q0v8cpzf+Px7\/+UROHWI9cRtbK9u4Nn4yvf\/Q7P\/fwJrl9ZYV5aanRElF46XURX6vdQToopuAyWqG1Bau3PoQDEEHHUEskcVSOZM0iZkTtff+zzfPrh0+xc3uaJHz5O1iHrowE333Idu5sX2Zzsce+3v0xSoZ59kw8d2WBnOmGvm1NqR6ktaCW5YSa4K8mFlAyX0Qoy76BUAvo9giKSUDHEE1mdQUqMUuKRR+\/j0w+fBuAvT79AomG8PGZ51LB9acrxj3+U+x+6Cx80PPu9H7NxYBWNls2toOsSJXpAIRXVIGXHXUhJ8Sy4DMeQOyggoRCKoCAOmjB1kjk5JU6dOsFnv3jPtZSwdX6H\/YcOcvT4BsdP3sANt9\/E0oEVIoI3fvUUS8NMqcsMmo7cVJBKjZaumxO1RQ1UA3MjN44nwRmvQleIkB5M9NFlOK4JxZHFAfjoNx+8djIDPPCN+\/jPEhGce+p55hcucvDG\/cw2M+3uFVa0RawiFtTaUrsZQoeaYK6knPGmwXU8JhX6PIPioSSMLE4OI6uRUW4\/dYyjR\/f9F4B\/L7UUXv31H9h+5VUGS8pgdcTB266n21xi621BZY7QgmSiJERqH2HJsZyxZoiP18aUAiwYMgQPZyDGAGWA0VThzk\/c8n\/B7FzY5KVfPMP8vQsMG0ChnU6YvNfiMme02lDb0p89BioJWcil7lgeoM0QP7xvSNcFtUANRUNRjBRCwhiE0hTh1psO\/E8g060Jf3\/6Bc798WWytAwHtU8dFaKFOjNolDxUIikmsZApoaZYymhukNRAHuIf3miY7LXMZ4V5VymlUmpFQpCoWBFMhAPro2sgdnemnH3lHGf+\/BrnXvwnTbSMvBCp4FSyVkIDLGDe50pJQfLATTATNCUkDyAZ5Ay5AR\/gD62\/xe5eZWenZWu3stMF2zOYzGGvhXknlA5+9IOfMN2dcuXiFruXtsilkCgkKgOtDK1jKQUrg8p8VGEcpBAG1tsMKS3qgWXDatC2hjGmnRk6SGxeHtEyQE6fPBArg8TeXm+V3DIhTsUJSRScqpmNw9dx\/uJFutI7AVejaRrWxsvMJlOyCY3C+nJmnIPVNOfIeuHEiXWo27z+9hV2plNKblm77ihP\/ub3nHl7xsqgsrExZtYGz760iz93rqIpEFUsGd4kRA3PDZ4ylhpUjdP3fIr5Sy9zcH0N1IlQjmwc4sKFyxxcX8VDmE+mnPzgCRoRdi+8yygHZd8Yn13iUPc611vH2lLHradG3HPTMS68vcV4CC4dB++8j8lff4vc8dXHolleoaswWBrjqUHVEXOSJ0QMAa7fv8YwJdZGDRcvbTNKjtTKbDrjwHjEZHePaDuWkhN7Mw6vLjFSWM7KQAvtlQtkq6yOKredXKNZgteef43xUGi8Y3joEHllFS8YO5MpWGK+vY3ILqC9F4regKsol997FykVSkVqpe7tQS1kM6QEEoHVQqL3xqOUGSdn7M5qkxglwbUwyrCz13LHR1Z487JSL3WsDGF85S0+8MDH8Mtn\/8G8bVHP1FLxZgjv\/0MggKeEqiIRRA00egBaK9J11wx+bWe4GFfOv84gD3ARVpdX2L+yhkdlMtlifWXMn1523jk75PzmHmfe22OYg0bnfKZ7Ezlw821RS6Gbz6ntjLQ0RkIo8z00NX06qB2eBwC95wa0BoogcdVD915cIxAqJoKr4AJKJZuhGnRdi1DYGDurA+PStLe5jcOdx+FfEghCLeMqGgkAAAAASUVORK5CYII=\u0022 data-src=\u0022https:\/\/avris.it\/image\/avris-function-mock_big.png\u0022 alt=\u0022Avris FunctionMock\u0022 class=\u0022border\u0022 width=\u0022900\u0022 height=\u0022600\u0022\u003E\u003C\/span\u003E\n                \n            \u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EFunctionMock is a simple and elegant way to mock away system\/global functions in your tests.\u003C\/p\u003E\n\u003Ch3\u003EInstalation\u003C\/h3\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs bash border\u0022\u003Ecomposer require --dev avris\/\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E-mock\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch3\u003EUsage\u003C\/h3\u003E\n\u003Cp\u003ELet\u2019s say you have a class that writes something to a file:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003E\u003Cspan class=\u0022hljs-meta\u0022\u003E\u0026lt;?php\u003C\/span\u003E\n\u003Cspan class=\u0022hljs-keyword\u0022\u003Enamespace\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EApp\u003C\/span\u003E\\\u003Cspan class=\u0022hljs-title\u0022\u003EService\u003C\/span\u003E;\n\n\u003Cspan class=\u0022hljs-class\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Eclass\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EWorkService\u003C\/span\u003E\n\u003C\/span\u003E{\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Epublic\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003Ework\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E(int $input)\u003C\/span\u003E: \u003Cspan class=\u0022hljs-title\u0022\u003Ebool\u003C\/span\u003E\n    \u003C\/span\u003E{\n        $result = \u003Cspan class=\u0022hljs-string\u0022\u003E\u0027correctResult\u0027\u003C\/span\u003E; \u003Cspan class=\u0022hljs-comment\u0022\u003E\/\/ ... calculate the result somehow\u003C\/span\u003E\n\n        $filename = \u003Cspan class=\u0022hljs-string\u0022\u003E\u0027\/tmp\/foo\u0027\u003C\/span\u003E;\n\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003Ereturn\u003C\/span\u003E file_put_contents($filename, $result);\n    }\n}\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003ETo test it, without actually using filesystem, you can use FunctionMock:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003E\u003Cspan class=\u0022hljs-meta\u0022\u003E\u0026lt;?php\u003C\/span\u003E\n\u003Cspan class=\u0022hljs-keyword\u0022\u003Enamespace\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EApp\u003C\/span\u003E\\\u003Cspan class=\u0022hljs-title\u0022\u003ETest\u003C\/span\u003E;\n\n\u003Cspan class=\u0022hljs-keyword\u0022\u003Euse\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EApp\u003C\/span\u003E\\\u003Cspan class=\u0022hljs-title\u0022\u003EService\u003C\/span\u003E\\\u003Cspan class=\u0022hljs-title\u0022\u003EWorkService\u003C\/span\u003E\n\u003Cspan class=\u0022hljs-title\u0022\u003Euse\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EPHPUnit\u003C\/span\u003E\\\u003Cspan class=\u0022hljs-title\u0022\u003EFramework\u003C\/span\u003E\\\u003Cspan class=\u0022hljs-title\u0022\u003ETestCase\u003C\/span\u003E;\n\n\u003Cspan class=\u0022hljs-class\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Eclass\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EServiceTest\u003C\/span\u003E \u003Cspan class=\u0022hljs-keyword\u0022\u003Eextends\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003ETestCase\u003C\/span\u003E\n\u003C\/span\u003E{\n    \u003Cspan class=\u0022hljs-comment\u0022\u003E\/** \u003Cspan class=\u0022hljs-doctag\u0022\u003E@var\u003C\/span\u003E WorkService *\/\u003C\/span\u003E\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Eprivate\u003C\/span\u003E $service;\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Eprotected\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EsetUp\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E()\u003C\/span\u003E\n    \u003C\/span\u003E{\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003E$this\u003C\/span\u003E-\u0026gt;service = \u003Cspan class=\u0022hljs-keyword\u0022\u003Enew\u003C\/span\u003E WorkService();\n    }\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Eprotected\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EtearDown\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E()\u003C\/span\u003E\n    \u003C\/span\u003E{\n        FunctionMock::clean();\n    }\n\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Epublic\u003C\/span\u003E \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-title\u0022\u003EtestWork\u003C\/span\u003E\u003Cspan class=\u0022hljs-params\u0022\u003E()\u003C\/span\u003E\n    \u003C\/span\u003E{\n        $mock = FunctionMock::create(\u003Cspan class=\u0022hljs-string\u0022\u003E\u0027App\u0027\u003C\/span\u003E, \u003Cspan class=\u0022hljs-string\u0022\u003E\u0027file_put_contents\u0027\u003C\/span\u003E, \u003Cspan class=\u0022hljs-keyword\u0022\u003Etrue\u003C\/span\u003E);\n\n        $returnValue = \u003Cspan class=\u0022hljs-keyword\u0022\u003E$this\u003C\/span\u003E-\u0026gt;service-\u0026gt;work(\u003Cspan class=\u0022hljs-number\u0022\u003E8\u003C\/span\u003E);\n\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003E$this\u003C\/span\u003E-\u0026gt;assertTrue($returnValue);\n        \u003Cspan class=\u0022hljs-keyword\u0022\u003E$this\u003C\/span\u003E-\u0026gt;assertEquals([[\u003Cspan class=\u0022hljs-string\u0022\u003E\u0027\/tmp\/foo\u0027\u003C\/span\u003E, \u003Cspan class=\u0022hljs-string\u0022\u003E\u0027correctResult\u0027\u003C\/span\u003E]], $mock-\u0026gt;getInvocations());\n    }\n}\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EIf your tests are in the same namespace with your tested classes, it\u2019s recommended to use \u003Ccode\u003E__NAMESPACE__\u003C\/code\u003E. \u003C\/p\u003E\n\u003Cp\u003EThe third parameter, the return value of the mocked function, can either be a literal or a callable:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022hljs php border\u0022\u003E$mock = FunctionMock::create(\u003Cspan class=\u0022hljs-keyword\u0022\u003E__NAMESPACE__\u003C\/span\u003E, \u003Cspan class=\u0022hljs-string\u0022\u003E\u0027file_put_contents\u0027\u003C\/span\u003E, \u003Cspan class=\u0022hljs-function\u0022\u003E\u003Cspan class=\u0022hljs-keyword\u0022\u003Efunction\u003C\/span\u003E \u003Cspan class=\u0022hljs-params\u0022\u003E($filename, $data)\u003C\/span\u003E \u003C\/span\u003E{\n    \u003Cspan class=\u0022hljs-keyword\u0022\u003Ereturn\u003C\/span\u003E $filename === \u003Cspan class=\u0022hljs-string\u0022\u003E\u0027\/tmp\/foo\u0027\u003C\/span\u003E;\n});\n\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EYou can disable\/re-enable the mock by invoking \u003Ccode\u003E$mock-\u0026gt;disable()\u003C\/code\u003E and \u003Ccode\u003E$mock-\u0026gt;enable()\u003C\/code\u003E,\nas well as clear the list of logged invocations with \u003Ccode\u003E$mock-\u0026gt;clearInvocations()\u003C\/code\u003E.\u003C\/p\u003E\n\u003Ch3\u003EKnown limitations\u003C\/h3\u003E\n\u003Cp\u003EFunctionMock works thanks to the fact that \u003Ccode\u003Efile_get_contents\u003C\/code\u003E inside of \u003Ccode\u003EApp\\Service\u003C\/code\u003E namespace references to the function\n\u003Ccode\u003EApp\\Service\\file_get_contents\u003C\/code\u003E and only if it\u2019s not defined it falls back to the global \u003Ccode\u003E\\file_get_contents\u003C\/code\u003E.\u003C\/p\u003E\n\u003Cp\u003EFunctionMock defines this \u003Ccode\u003EApp\\Service\\file_get_contents\u003C\/code\u003E function on the fly\nand makes it adjustable to your needs in the runtime.\u003C\/p\u003E\n\u003Cul\u003E\n\u003Cli\u003EIf you already have invoked \u003Ccode\u003Efile_get_contents\u003C\/code\u003E inside of \u003Ccode\u003EApp\\Service\u003C\/code\u003E before registering a mock,\nPHP will continue using the global function and it cannot be overwritten anymore.\u003C\/li\u003E\n\u003Cli\u003EIf you\u2019re using \u003Ccode\u003E\\file_get_contents\u003C\/code\u003E (explicitly global namespace) inside your tested class,\nthere\u2019s obviously no way to mock it.\u003C\/li\u003E\n\u003Cli\u003EAfter being registered, mock function cannot be really unset, only disabled.\u003C\/li\u003E\n\u003C\/ul\u003E\u003Csvg xmlns=\u0022http:\/\/www.w3.org\/2000\/svg\u0022 style=\u0022display: none;\u0022\u003E\u003C\/svg\u003E","tags":["function","global function","mock","namespaces","php","tests"],"hasMore":true,"image":"https:\/\/avris.it\/image\/avris-function-mock_small.png","introLite":"\u003Cfigure\u003E\u003Ca href=\u0022https:\/\/avris.it\/image\/avris-function-mock_big.png\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Cimg src=\u0022https:\/\/avris.it\/image\/avris-function-mock_mini.png\u0022 alt=\u0022Avris FunctionMock\u0022 width=\u0022240\u0022 height=\u0022160\u0022 loading=\u0022lazy\u0022\u003E\u003C\/a\u003E\u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EFunctionMock is a simple and elegant way to mock away system\/global functions in your tests.\u003C\/p\u003E","contentLite":"\u003Cfigure\u003E\u003Ca href=\u0022https:\/\/avris.it\/image\/avris-function-mock_big.png\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003E\u003Cimg src=\u0022https:\/\/avris.it\/image\/avris-function-mock_mini.png\u0022 alt=\u0022Avris FunctionMock\u0022 width=\u0022240\u0022 height=\u0022160\u0022 loading=\u0022lazy\u0022\u003E\u003C\/a\u003E\u003C\/figure\u003E\u003C\/p\u003E\n\u003Cp\u003EFunctionMock is a simple and elegant way to mock away system\/global functions in your tests.\u003C\/p\u003E\n\u003Ch3\u003EInstalation\u003C\/h3\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022language-bash\u0022\u003Ecomposer require --dev avris\/function-mock\u003C\/code\u003E\u003C\/pre\u003E\n\u003Ch3\u003EUsage\u003C\/h3\u003E\n\u003Cp\u003ELet\u2019s say you have a class that writes something to a file:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022language-php\u0022\u003E\u0026lt;?php\nnamespace App\\Service;\n\nclass WorkService\n{\n    public function work(int $input): bool\n    {\n        $result = \u0027correctResult\u0027; \/\/ ... calculate the result somehow\n\n        $filename = \u0027\/tmp\/foo\u0027;\n\n        return file_put_contents($filename, $result);\n    }\n}\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003ETo test it, without actually using filesystem, you can use FunctionMock:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022language-php\u0022\u003E\u0026lt;?php\nnamespace App\\Test;\n\nuse App\\Service\\WorkService\nuse PHPUnit\\Framework\\TestCase;\n\nclass ServiceTest extends TestCase\n{\n    \/** @var WorkService *\/\n    private $service;\n\n    protected function setUp()\n    {\n        $this-\u0026gt;service = new WorkService();\n    }\n\n    protected function tearDown()\n    {\n        FunctionMock::clean();\n    }\n\n    public function testWork()\n    {\n        $mock = FunctionMock::create(\u0027App\u0027, \u0027file_put_contents\u0027, true);\n\n        $returnValue = $this-\u0026gt;service-\u0026gt;work(8);\n\n        $this-\u0026gt;assertTrue($returnValue);\n        $this-\u0026gt;assertEquals([[\u0027\/tmp\/foo\u0027, \u0027correctResult\u0027]], $mock-\u0026gt;getInvocations());\n    }\n}\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EIf your tests are in the same namespace with your tested classes, it\u2019s recommended to use \u003Ccode\u003E__NAMESPACE__\u003C\/code\u003E. \u003C\/p\u003E\n\u003Cp\u003EThe third parameter, the return value of the mocked function, can either be a literal or a callable:\u003C\/p\u003E\n\u003Cpre\u003E\u003Ccode class=\u0022language-php\u0022\u003E$mock = FunctionMock::create(__NAMESPACE__, \u0027file_put_contents\u0027, function ($filename, $data) {\n    return $filename === \u0027\/tmp\/foo\u0027;\n});\u003C\/code\u003E\u003C\/pre\u003E\n\u003Cp\u003EYou can disable\/re-enable the mock by invoking \u003Ccode\u003E$mock-\u0026gt;disable()\u003C\/code\u003E and \u003Ccode\u003E$mock-\u0026gt;enable()\u003C\/code\u003E,\nas well as clear the list of logged invocations with \u003Ccode\u003E$mock-\u0026gt;clearInvocations()\u003C\/code\u003E.\u003C\/p\u003E\n\u003Ch3\u003EKnown limitations\u003C\/h3\u003E\n\u003Cp\u003EFunctionMock works thanks to the fact that \u003Ccode\u003Efile_get_contents\u003C\/code\u003E inside of \u003Ccode\u003EApp\\Service\u003C\/code\u003E namespace references to the function\n\u003Ccode\u003EApp\\Service\\file_get_contents\u003C\/code\u003E and only if it\u2019s not defined it falls back to the global \u003Ccode\u003E\\file_get_contents\u003C\/code\u003E.\u003C\/p\u003E\n\u003Cp\u003EFunctionMock defines this \u003Ccode\u003EApp\\Service\\file_get_contents\u003C\/code\u003E function on the fly\nand makes it adjustable to your needs in the runtime.\u003C\/p\u003E\n\u003Cul\u003E\n\u003Cli\u003EIf you already have invoked \u003Ccode\u003Efile_get_contents\u003C\/code\u003E inside of \u003Ccode\u003EApp\\Service\u003C\/code\u003E before registering a mock,\nPHP will continue using the global function and it cannot be overwritten anymore.\u003C\/li\u003E\n\u003Cli\u003EIf you\u2019re using \u003Ccode\u003E\\file_get_contents\u003C\/code\u003E (explicitly global namespace) inside your tested class,\nthere\u2019s obviously no way to mock it.\u003C\/li\u003E\n\u003Cli\u003EAfter being registered, mock function cannot be really unset, only disabled.\u003C\/li\u003E\n\u003C\/ul\u003E","words":346,"readTime":2,"lang":"en"}}}}}