Say I'm writing a wrapper for some third party api and I have a method like this:
public function fetchSomeData()
{
$url = $this->makeUrl($someArgs);
$response = $this->call($url);
$this->save($response);
return $response;
}
Is this a code smell and bad design in general (considering that I want to test this and all the methods inside are private) and if is what would be some good ways to refactor this?
No, these things aren't necessarily a code smell. You may definitely want to group some related calls in a method to make it easier to use.
You shouldn't be trying to test private
methods, only public
ones (since private
methods are really just are a public
method made more easily readable by splitting it up).
I don't know PHP but it seems to me that you're trying to make a webrequest and you somehow save the response.
The first thing that's important here is that you have to make it a unit test instead of an integration test (integration tests are important as well but this is tagged as unit testing). Integration tests interact with some underlying system outside of your code: the filesystem, current datetime, webrequests, databases, etc.
A good solution to this would be creating an interface that's being inherited by your datasource (your webrequest in this case).
interface IDataSource {
public function MakeUrl($args);
}
And now you can use Dependency Injection via the constructor or setter to inject your datasource into the class.
As to your question on how to test this: you don't test the private methods. Create a test that injects your fake IDataSource
into the class, call it with your parameters and see what it returns and perform your asserts based on that.
Say if you writing common set of methods to deal with some API than create function inside class that perform some API operations.
And create a separate file, like controller file. And in this controller file create an object of API class and call its method as you need them and as per your business logic.
So instead of
public function fetchSomeData()
{
$url = $this->makeUrl($someArgs);
$response = $this->call($url);
$this->save($response);
return $response;
}
you should create one .php file and create object like
$obj = new APIClass();
and than do like this
$url = $obj->makeUrl($someArgs);
$response = $obj->call($url);
$obj->save($response);