lundi 27 juillet 2015

Php, is it good to mock database resultset?

In my model:

class UsersModel
{
    public function getUsers()
    {
        return SELECT id,username,rights FROM database
    }
}

and the result is:

array{
    array{'id' => 1, 'username' => 'a', 'rights' => 4},
    array{'id' => 2, 'username' => 'b', 'rights' => 8},
    array{'id' => 4, 'username' => 'c', 'rights' => 7},
}

this then gets formatted:

class Helper
{
    function formatUsers (array $source)
    {
        foreach ($source as $item)
        {
             $item['usernameF'] = $item['username'].'.'.$item['id'];
        }
        return $source;
    }
}

and the result is:

array{
    array{'id' => 1, 'username' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
    array{'id' => 2, 'username' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
    array{'id' => 4, 'username' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
}

and outputting in the view:

foreach ($users as $item)
{
    echo $item['usernameF'].' = '.$item['rights'].'<br>';
}

so far so good, now lets test it.

testModel:

assertEquals ($result, array{
    array{'id' => 1, 'username' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
    array{'id' => 2, 'username' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
    array{'id' => 4, 'username' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
});

testHelper:

here comes the difficulties. I can mock the getUsers() method to enforce a result.

$mock->setMock ($this->once()->method('getUsers')->willReturn(array{
    array{'id' => 1, 'username' => 'a', 'rights' => 4},
    array{'id' => 2, 'username' => 'b', 'rights' => 8},
    array{'id' => 4, 'username' => 'c', 'rights' => 7}
});

assertEquals ($result, array{
    array{'id' => 1, 'username' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
    array{'id' => 2, 'username' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
    array{'id' => 4, 'username' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
}

BUT what if the DB scheme changes? What if I accidentally mistype a field, lets say "usernmame'. Result will be:

array{
    array{'id' => 1, 'usernmame' => 'a', 'rights' => 4},
    array{'id' => 2, 'usernmame' => 'b', 'rights' => 8},
    array{'id' => 4, 'usernmame' => 'c', 'rights' => 7},
}

of course the test of model fails, so I change it too:

testModel:

assertEquals ($result, array{
    array{'id' => 1, 'usernmame' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
    array{'id' => 2, 'usernmame' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
    array{'id' => 4, 'usernmame' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
});

so all test passes - but in production, the view will fail with "wrong index; username"! So what would be the best approach?

Aucun commentaire:

Enregistrer un commentaire