3
votes

I need help with PHPUnit and some methods. How should you guys write tests in PHPUnit to reach a high code coverage for the following properties and methods?

I'm pretty new to PHPUnit and could need some help. I've just write some test cases for more basic code. This class generates flash messages for the end user, and store it in a session.

Extremely grateful for some help. Any ideas?

private $sessionKey = 'statusMessage';
private $messageTypes = ['info', 'error', 'success', 'warning']; // Message types.
private $session = null;
private $all = null;

public function __construct() {
    if(isset($_SESSION[$this->sessionKey])) {
        $this->fetch();
    }
}

public function fetch() {
    $this->all = $_SESSION[$this->sessionKey];
}

public function add($type = 'debug', $message) {
    $statusMessage = ['type' => $type, 'message' => $message];

    if (is_null($this->all)) {
        $this->all = array();
    }

    array_push($this->all, $statusMessage);

    $_SESSION[$this->sessionKey] = $this->all;
}

public function clear() {
    $_SESSION[$this->sessionKey] = null;
    $this->all = null;
}

public function html() {
    $html = null;

    if(is_null($this->all))
        return $html;

    foreach ($this->all as $message) {

        $type = $message['type'];
        $message = $message['message'];

        $html .= "<div class='message-" . $type . "'>" . $message . "</div>";

    }

    $this->clear();

    return $html;
}

I have setup an setup-case, like this:

protected function setUp() {
    $this->flash = new ClassName();
}

Also tried one test case:

public function testFetch() {
    $this->assertEquals($this->flash->fetch(), "statusMessage", "Wrong session key.");
}

But gets an error message telling me: "Undefined variable: _SESSION" If I then try:

public function testFetch() {
    $_SESSION = array();
    $this->assertEquals($this->flash->fetch(), "statusMessage", "Wrong session key.");
}

I get another error message telling: "Undefined index: statusMessage"

1
1. Move all decoration (html) out of this code 2. Separate your flash messages storage from the other logic. 3. ????????? 4. PROFIT!!!1111 - zerkms
I can't change this code. Need to test it as it is now. Do you have any idea how? Please help. :) - Treps
Try something like this: function testWithoutSessionKey() { $_SESSION = array(); $yourClass = new YourclassName(); $this->assertNull($yourClass->html()); } function testWithSomeSessionKey() { $_SESSION = array( 'statusMessage' => array(...)); $yourClass = new YourclassName(); $this->assertSame($expect, $yourClass->html()); } Hope this help - Matteo
@Matteo: testWithoutSessionKey() worked fine. :) Could you answer this question with information how you would test these methods? Please! :) I have updated the question. - Treps
You are on the good way! You have found a bug in your code! Now you can fix it (you must check in the fetch method that the key is set before accessing it). I suppose the second approach is good. I should post only the code you have put in the answer - Matteo

1 Answers

2
votes

Try something like this:

    function testWithoutSessionKey() { 
$_SESSION = array(); 
$yourClass = new YourclassName(); 
$this->assertNull($yourClass->html()); } 

function testWithSomeSessionKey() { 
$_SESSION = array( 'statusMessage' => array(...)); 
$yourClass = new YourclassName(); 
$this->assertSame($expect, $yourClass->html()); 
} 
  1. You can't instantiate your class in the setup because your constructor need that the SESSION variable may exist(so you can test that can have some value inside).
  2. You can evalutate (assert) only the ouptput of a method, so you can't assert that the message of the return of the method fetch.

In your method testFecth you have found a bug! Thanks to the test for this. Try fixing it with checking as you do in the construct :

public function fetch() {
if (isset($_SESSION[$this->sessionKey]))
    $this->all = $_SESSION[$this->sessionKey];
}    

Hope this help