Answer the question
In order to leave comments, you need to log in
How to correctly cover the code given in the example with tests?
I do not need to be convinced that autotests are needed during development, I have already done this for myself.
The main question is how to write an autotest so that it is a help, and not a burden?
I have already read a lot of articles and watched a number of videos about autotests, but it was all either purely theoretical material,
or more “academic” examples were dealt with there ...
Actually, I have a specific task (actually a simplified version of a real task), with which I can not cope and ask for help.
You need to write a function / class that would receive some text parameter $paramX as input (in a real task, there are several) and check the presence of records in the database table that satisfy a condition that depends on $paramX.
If there is at least one such entry, then return True, otherwise (if there is none) False.
Here is an example of my implementation.
class GetSomeValue
{
protected $paramX;
protected $db;
protected $timedate;
public function __construct(string $paramX)
{
$this->paramX = $paramX;
// Инстанс от фреймворка для работы с БД
$this->db = DBManager::getInstance();
// Инстанс от фреймворка для работы с датой и временем
$this->timedate = TimeDate::getInstance();
}
public function getValue(): bool
{
$row = $this->getDbData($this->getCompleteSql());
return !empty($row);
}
/**
* Вынес в отдельную функцию и реализовал такую передачу параметров, чтобы можно было замокать
* @param string $sql
* @return array|false Если данные не найдены или ошибка выполнения запроса, то false, иначе массив с данными одной записи
*/
protected function getDbData(string $sql)
{
return $this->db->fetchOne($sql);
}
protected function getCompleteSql(): string
{
return strtr($this->getSql(), $this->getSqlParams());
}
protected function getSql(): string
{
return "
SELECT
'x'
FROM
table_1
WHERE
field1 = 'CONST1' AND
field2 = <paramX> AND
date_open <= <curDate> AND
date_close IS NULL
";
}
protected function getSqlParams(): array
{
$params = [
'<paramX>' => $this->paramX,
'<curDate>' => $this->getCurDate(),
];
return array_map([$this->db, 'quoted'], $params);
}
/**
* Вынес в отдельную функцию, чтобы можно было замокать
* @return string Дата в формате БД yyyy-mm-dd
*/
protected function getCurDate(): string
{
return $this->timedate->getNowDbDate();
}
}
Answer the question
In order to leave comments, you need to log in
https://github.com/index0h/php-conventions#7-testi...
Specifically for the code:
1. Don't worry about splitting everything into separate methods. You will not reduce the actual complexity, instead you will force the engineer who will watch it to run around the class to somehow connect your one-liners. Specifically, in your case, it is worth making only one getValue method, and what you scattered over the protected ones should be stuffed into getValue.
2. db and timedate instances should be passed to the constructor explicitly, and static should be abandoned as much as possible.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question