Должна ли функция, которая просто передает аргумент другой функции, выполнить проверку типа этого аргумента?

Учитывая следующие два (простой / случайный) PHP-методы в одном классе:

/*
* @param $a An int to play with
* @param $b An int to play with
* @param $c An int to play with
*
* @throws InvalidArgumentException when either $a, $b, or $c are not an int
*
* @return A new int
*/
public function1($a, $b, $c) {
if(!is_int($a)) throw new InvalidArgumentException('$a must be an int');
if(!is_int($b)) throw new InvalidArgumentException('$b must be an int');

$x = $a * $b;

$y = $this->function2($c);

return $x - $y;
}

/*
* @param $c An int to play with
*
* @throws InvalidArgumentException when $c is not an int
*
* @return A new int
*/
private function2($c) {
if(!is_int($c)) throw new InvalidArgumentException('$c must be an int');

return $c + 1;
}

Две части вопроса:

  • Должна ли функция1 () также проверять тип аргумента для $ c?
  • При тестировании, скажем, с использованием PHPUnit, достаточно ли проверить неверный аргумент для function2, или я должен также написать второй тест для проверки передачи плохого $ c в function1?

Возможно, что function2 () может быть вызвана другими функциями, кроме function1 ().

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

2

Решение

Это действительно не имеет значения, если function1 проверяет параметр c или нет, это в значительной степени стилистический выбор. Некоторым людям нравится выполнять ВСЕ проверки в начале функции, потому что это означает, что функция может быть прервана как можно скорее, без какой-либо ненужной обработки. Если перед вызовом произошла значительная обработка function2 тогда было бы больше оснований для проверки, но в данном случае важно то, что параметр проверяется до его фактического использования.

Что касается вашего второго вопроса, ДА, вы должны проверить передачу неверного параметра в function1, Лично я не думаю, что вы должны тестировать передачу плохого параметра в function2, На самом деле, с точки зрения модульного теста, вы даже не должны знать, что function2 существует.

Я не программист на PHP, поэтому не стесняйтесь голосовать «за», если это далеко не так, но на основе других языков, которые я использовал, публичные методы класса определяют открытый интерфейс и, следовательно, тестируемый API для класса. Другими словами, если я являюсь клиентом для вашего класса, я могу вызвать любой из открытых методов вашего класса, включая function1, Когда клиент вызывает публичный метод, существуют определенные ожидания (входы / выходы / выполненная обработка), которые можно протестировать, но клиент не должен знать или не заботиться о том, чтобы эти ожидания были выполнены / реализованы в одном методе или с использованием нескольких методы. Итак, с точки зрения клиентов ваш код мог бы быть написан так:

/*
* @param $a An int to play with
* @param $b An int to play with
* @param $c An int to play with
*
* @throws InvalidArgumentException when either $a, $b, or $c are not an int
*
* @return A new int
*/
public function1($a, $b, $c) {
if(!is_int($a)) throw new InvalidArgumentException('$a must be an int');
if(!is_int($b)) throw new InvalidArgumentException('$b must be an int');
if(!is_int($c)) throw new InvalidArgumentException('$c must be an int');

$x = $a * $b;

$y = $c + 1;

return $x - $y;
}

Если бы вы изначально написали свой код, подобный этому, и написали тесты для этого поведения, вы могли бы реорганизовать свой код, добавив function2 поделиться функциональностью с другими безопасными методами, зная, что ваши тесты общедоступного интерфейса проверяют, что класс по-прежнему работает с клиентами, как и ожидалось. Отсюда и термин «с уверенностью рефакторинг», который вы время от времени слышите.

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

1

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

Других решений пока нет …

По вопросам рекламы [email protected]