Как провести юнит-тест как то так?

У меня есть такой пример, который основан на генераторе ключей Laravel:

public function generateRandomKey(): string
{
$generatedKey = base64_encode(random_bytes(16));

// Encrypt the generated key with our public key so it is not a 'plain password' anymore.
$value = openssl_public_encrypt($generatedKey, $crypted, $this->getPublicKey());

if (!$value) {
throw new \RuntimeException('Encryption failed: could not generate a random key.');
}

return base64_encode($crypted);
}

Я хотел бы провести модульные тесты, и я могу ожидать RuntimeException, Я хотел бы иметь 100% покрытие кода, но я также не хочу форсировать сценарий только для того, чтобы получить 100% покрытие кода.

В этом примере я бы хотел, чтобы PHPUnit ударил исключение. Я не могу предоставить неправильный ключ, потому что мой getPublicKey() является частным и выдаст ошибку, прежде чем я доберусь до ошибки в этом методе.

Вызвать ошибки дешифрования не так сложно, так как я могу просто указать случайное значение, которое не было должным образом зашифровано.

Итак, как я смогу протестировать подобный сценарий и достичь 100% покрытия кода. Возможно ли или даже целесообразно протестировать что-то подобное или лучше игнорировать это комментарием PHPUnit или чем-то еще?

Приветствия.

2

Решение

Если ваша цель — 100% охват, вам придется пойти по пути потенциально «чрезмерной оптимизации» вашего кода ради него. В этом случае это не было бы слишком большим хитом все же.

Один из вариантов заключается в том, чтобы абстрагировать строку шифрования в ее собственный частично смоделируемый метод, однако, делая это (и сообщая PHPUnit, что он будет возвращать), вы фактически просто проверяете, что исключение может быть выдано (в буквальном смысле).

Семантически говоря, методы получения / установки обычно бывают публичными, хотя это не строго соблюдается никакими органами. Я полностью понимаю, почему ты не хочешь getPrivateKey как часть вашего API, но вы мог целесообразно добавить setPrivateKey метод к вашему общедоступному API — это решит вашу проблему с модульным тестированием:

# File: YourClass
public function setPrivateKey(string $key) : YourClass
{
$this->privateKey = $key;
return $this;
}

Затем:

# File: YourClassTest
/**
* @expectedException RuntimeException
* @expectedExceptionMessage Encryption failed: could not generate a random key.
*/
public function testGenerateRandomKeyThrowsExceptionWhenCannotEncrypt()
{
$class = new YourClass;
$class->setPrivateKey('highly-unlikely-to-be-a-valid-private-key');
$class->generateRandomKey();
}

Конечно, делая это, вы сталкиваетесь с аргументом, что «вы не должны тестировать код, который вам не принадлежит», то есть openssl метод. Это компромисс, который вы сделаете, чтобы достичь 100% покрытия, если это ваша цель.

1

Другие решения

Тебе нужно заглушить openssl_public_encrypt вернуть ложь.

Предполагая ваш generateRandomKey метод принадлежит классу StephanVтест может выглядеть так:

namespace Tests;

function openssl_public_encrypt()
{
return false;
}

class StephanVTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \RuntimeException
*/
public function testGenerateRandomKeyThrowsException()
{
$cut = new StephanV;
$cut->generateRandomKey();
}
}
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector