Check PHPUnit file_get_contents

I have a class that has a method that uses the global PHP function file_get_contents . I need to test a method on a class without calling a global function.

I know that I could use namespaces to override what is returned from file_get_contents , however my tests are already in a separate namespace, so I cannot just map the namespaces to the class.

Here is the code:

Class

 <?php namespace MyVendor\MyProject; class MyClass { private $someProperty; public function __construct($override = '') { $this->someProperty = $override; } public function myMethod() { $request = 'http://domain.com'; $response = $this->someMethodUsingGlobals($request); // Do something with the response.. } public function someMethodUsingGlobals($url) { return json_decode(file_get_contents($url),true)['results'][0]; } } 

Test

 <?php namespace MyProjectTests; public function test_it_does_something_with_the_response() { $sut = new MyClass(); $response = $sut->myMethod(); $this->assertEquals('Some expectation', $response); } 

I need to make fun of the someMethodUsingGlobals() method in a class, but am not quite sure how to do this.

+5
source share
2 answers

You can archive it using partially Mock Objects: you can only make fun of a specific method of your class and execute (and test) another method.

Further link here

As an example, suppose your modified class:

 <?php namespace Acme\DemoBundle\Service; class MyClass { public function myMethod() { $request = 'http://domain.com'; $response = $this->someMethodUsingGlobals($request); // Do something with the response.. return $response; } public function someMethodUsingGlobals($url) { return json_decode(file_get_contents($url),true)['results'][0]; } } 

You can test the following class of tests:

 <?php namespace Acme\DemoBundle\Tests; class MyProjectTest extends \PHPUnit_Framework_TestCase { public function test_it_does_something_with_the_response() { $sut = $this->getMock('Acme\DemoBundle\Service\MyClass', array('someMethodUsingGlobals') ); // Set up the expectation for the someMethodUsingGlobals() method // to be called only once and with the string 'http://domain.com' // as its parameter. $sut->expects($this->once()) ->method('someMethodUsingGlobals') ->with($this->equalTo('http://domain.com')) ->willReturn('Some expectation'); $response = $sut->myMethod(); $this->assertEquals('Some expectation', $response); } } 

Thus, the someMethodUsingGlobals method is not executed and returns the values โ€‹โ€‹defined in the layout definition. The myMethod method myMethod executed and processed using a mock function.

Hope for this help

+2
source

I know that I can use namespaces to override what is returned from file_get_contents, however my tests are in a separate namespace already so I cannot just map the namespaces to the class.

It does not make sense. You can declare a function inside the namespace in the test folder or even in the test file itself:

 <?php namespace MyVendor\MyProject { file_get_contents() { ... } } namespace MyProjectTests { use PHPUnit\Framework\TestCase; class ProjectTest extends TestCase { ... } } 

When using a separate file, just include .

It would be even better to use a virtual file system for testing. Thus, you can precisely control the contents of the returned file on a test basis, without even touching disks.

-1
source

Source: https://habr.com/ru/post/1232714/


All Articles