Answer the question
In order to leave comments, you need to log in
How to test the authorization method?
I am writing a test for the user authorization method. The test should not pass if the method authorized the user with an incorrect password. That is, in fact, the test should check whether the password hash comparison is present in the method.
This is my first time writing a test, so I'm not sure if I'm doing it right. It seems to me that the authorization test should not contain the password hashing logic, but I don’t know how to do it otherwise. Testing gurus help me.
Sample implementation of authorization to understand what I'm testing, in fact it does not exist.
class UserManager implements UserManagerInterface
{
public function makePasswordHash($password)
{
return md5($password); // какое-то хеширование
}
}
class AuthorizationManager implements AuthorizationManagerInterface
{
public function authorizeUserByLogin($login, $password)
{
$user = $this->userManager->getUserByLogin($login);
$passwordHash = $this->userManager->makePasswordHash($password);
if ($passwordHash === $user->getPasswordHash()) {
// авторизуем пользователя
return true;
}
}
}
class AuthorizationManagerTest extends TestCase
{
/**
* Не должно авторизовывать пользователя по правильному логину но по неправильному паролю
* @test
*/
public function dontAuthorizeUserByLoginAndWrongPassword()
{
$userManagerMock = $this->getUserManagerMock();
$authorizationManager = new AuthorizationManager($tokenManagerMock, $userManagerMock);
$login = 'login';
$password = 'wrongPassword';
$userId = 15;
$passwordHash = md5('password'); // Логика хеширования пароля в тесте, мне кажется это не правильно
$userManagerMock->method('getUsersByLogin')
->willReturn([$this->getUserMock($userId, $login, $passwordHash)]);
$result = $authorizationManager->authorizeUserByLogin($login, $password);
$this->assertEquals(false, $result, 'Пользователь был авторизован по верному логину и неверному паролю');
}
}
Answer the question
In order to leave comments, you need to log in
Isn't everything too complicated? You need to check that authentication is happening correctly and that's it. Enough test:
$tokenManagerMock = "???";
$userManagerMock = $this->getUserManagerMock();
$authorizationManager = new AuthorizationManager($tokenManagerMock, $userManagerMock)
$login = "Bob";
$this->assertTrue(
$authorizationManager->authorizeUserByLogin($login, "true password")
);
$this->assertFalse(
$authorizationManager->authorizeUserByLogin($login, "false password")
);
$this->assertFalse(
$authorizationManager->authorizeUserByLogin($login, "")
);
$this->assertFalse(
$authorizationManager->authorizeUserByLogin($login, null)
);
Rewrote the code, I think it's better. Now the test checks that the hashes were taken into account in the authorization method, while the implementation of hashing in the UserManager does not matter.
/**
* Не должно авторизовывать пользователя по правильному логину но по неправильному паролю
* @test
*/
public function dontAuthorizeUserByLoginAndWrongPassword()
{
$userManagerMock = $this->getUserManagerMock();
$authorizationManager = new AuthorizationManager($userManagerMock);
$login = 'login';
$password = 'wrongPassword';
$userId = 15;
$passwordHash = md5('password');
$userManagerMock->method('getUsersByFilter')
->willReturn([$this->getUserStub($userId, $login, $passwordHash)]);
$userManagerMock->method('makePasswordHash')
->will($this->returnCallback(function($password) {
return md5($password);
}));
$result = $authorizationManager->authorizeUserByLogin($login, $password);
$this->assertFalse($result, 'Пользователь был авторизован по корректому логину и неверному паролю');
}
How I solved a similar situation in my case:
using Guzzle;
Then you pass arbitrary data from the provider with password, login options and look at the response code - was there a redirect (Successful or not the authorization method). Of course you allow redirects and enable cookies.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question