Reputation: 61
I’m trying to write a simple unit test for a single function in my Slim PHP application. The function creates a directory using mkdir() and I want the test to assert that the directory is created successfully. When tested using the front end application, the folder is created successfully, however when running the test, the directory is not found
1) TestController::testCreate mkdir(): No such file or directory
We are autoloading classes using the follow:
//composer.json
"autoload": {
"psr-4": {
"App\\": "app",
"tests\\": "tests/"
}
}
This is the function that creates the directory:
//Controllor.php
public function create($request, $response){
mkdir("../public/folder");
}
Using the application, this creates a directory in the following location as expected
-app
-public/folder
This is an example of the test function:
//TestController.php
public function testCreate(){
$controller = new Controller($this->container);
$request = $this->requestFactory();
$response = new \Slim\Http\Response();
$response = $controller>create($request, $response, []);
//Assertions below..
}
I am using a phpunit.xml to bootstrap the autoload.php file by inserting bootstrap="vendor/autoload.php" into the config file.
I have also tried to require the vendor/autoload.php from the TestController.php and have tried to manually set $_SERVER['DOCUMENT_ROOT']
in TestController.php
How can I autoload the namespaces while running TestController.php so that the create() function is invoking mkdir() from the correct location?
Upvotes: 3
Views: 1311
Reputation: 4952
You have multiple options
Upvotes: 1
Reputation: 2357
Well, there is a small problem and a bigger problem.
Small one -- you're loosing context, specifically working directory. Thus, not clear where your directory is being created, and if that place is actually writable. To overcome this, I'd make a configurable value -- a directory name where things should happen. For real use case I'd supply $_SERVER['DOCUMENT_ROOT'] (or whatever other value is suitable), and for tests I'd use /tmp
(or better sys_get_temp_dir()
).
To better word first problem (one you're asking about):
array_keys()
function available"Bigger one -- this is not a unit test, because you're checking how your code interacts with some external entity, in this case filesystem. This is a functional test. To make it unit test, you need to mock mkdir()
, and to do that you need to abstract it away behind some interface like this:
interface DirMaker {
public function mkdir($name);
}
Implementation of that interface could handle configuration too. And in test you could provide a mock that just acknowledges the fact that mkdir()
was called, as expected.
Upvotes: 1