Pregunta

I am new to testing, and having some struggle to figure out what and how to test some functions.

take this method as en example:

public static function generateResponse(array $result)
{

    return new Response($result['body'], $result['headers'], $result['code']);

}

what should i test? The first thing that comes to mind is that i want to make sure that the array has the required keys.

and also make sure that it is returning a Response object.

Someone having some tips for a TestNoobie :)

¿Fue útil?

Solución

You can't really test very much in that particular method.

Testing boils down to writing test code that calls a function of your production code. Here, you'd write a line that does a call to that static method.

A test would then check if the expected return value is really returned. In your case, the function you show has absolutely no way to do something fancy. It will accept that array you pass as a parameter, grab some values from it, create a Response object with these values, and return it.

From the outside of that class, in your test, you can only vary the array that you are passing into the function, and your expectation is to always get an object of class Response. We cannot see if the parameters you pass will get somewhere and if you can detect whether or not they got passed correctly, but @gontrollez assumed this can be done by checking some public properties (he might be wrong, he also does not know your code).

So writing tests is like the first time you use your own production code. Assume you want to write a mail address validator. Simple thing, call a function with a string (the mail address), and return true for valid addresses, and false otherwise.

You'd test your function by writing test code that calls that validator with several working mail addresses and expects true as return value, and several invalid strings that should return false.

The problem with your code you gave: It is hard to test in depth. It does not allow simple tests for all aspects, only for the obvious fact that the test should check the class of the returned object. Testing details will get messy.

So in addition to you being a beginner in the testing business, you also chose a hard target as well. I can understand you are confused.

Also, you cannot test that the array has the required keys. Because that must take place in your production code, and it is called validation. If you write code in your static function that check for the array keys and somehow fails if they are not there (throw an exception), your test can then check if the exception really is thrown if you fail to pass all array keys, and that you get a Response object if all is correct.

Otros consejos

Don't write tests, refactor the code instead:

public static function createResponse($body, $headers, $code)
{
    return new Response($body, $headers, $code);
}

and change all the places where that global static function has been invoked.

As the code already works (green), you stop with testing and you do the refactoring (blue).

You would check that a Response object is returned and has the right properties assigned:

$body = 'body';
$headers = 'headers';
$code = 'code';
$response = Class::generateResponse(
    array(
        'body' => $body,
        'headers' => $headers,
        'code' => $code
    )    
);
$this->assertInstanceOf('Response', $response);
$this->assertEquals($body, $response->body);
$this->assertEquals($headers, $response->headers);
$this->assertEquals($code, $response->code);

This is how you can test the method. I agree with hakre's refactoring suggestion but you asked how to test your method.

Another point: Static methods will make your code less testable, as you won't be able to (easily) replace the real objects or classes by mocks, when you need it. Take a look at this good explanation.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top