How would you test an action/controller like this?

Hey there,

I’m wondering what would be the best approach to test an action/controller like this one.

    public function __invoke(Request $request, Response $response)
{
    if ($this->container->userValidator->hasErrors()) {
        return JSON::error($response, JSON::WRONG_CREDENTIALS);
    }

    $email = $request->getParam('email');
    $password = $request->getParam('password');
    $user = $this->container->user->findByEmail($email);
    if ($user == false || !password_verify($password, $user['password'])) {
        return JSON::error($response, JSON::WRONG_CREDENTIALS);
    }

    return JSON::success($response, ['token' => $user['token']);
}

JSON is just a bunch of helper methods that format the response object, it has its own tests and I don’t really worry about it. However, I wonder what would be the approach for the container and the password_verify function.

Would you mock the container with the user and userValidator objects or just let them run with a test database? maybe this controller should be rewritten so it can be tested easily?

You should mock from the container “userValidator” and “user”.
Then create a request with custom params and test the different results.
I prefer to pass params in the invoke method and put the container out of the controller, so you have less thing to mock.

As I started mocking “user” I realised it had more dependencies from the container and I also had to mock them, it was all a bit messy and much more work than I wanted to do.

I changed the controller constructor to accept “userValidator” and “user” as params instead of the container, as you proposed, and it certainly is easier to test things this way. :slight_smile: