У меня есть проект в SF4, и я использую phpunit 6.5.8. Я тестировал сервис, использующий iconv:
iconv('UTF-8', 'ASCII//TRANSLIT', $string)
Когда я использую эту службу в приложении и когда $ string имеет значение: «ąbć», возвращается «abc», но когда та же служба запускается в phpunit, возвращается «? B?».
Не понимаю, почему не работает ... Конечно, тест отрицательный, но в приложении работает хорошо.






Хорошо, я решил проблему. Php в CLI не устанавливает языковой стандарт. Так что надо ставить перед тестами.
locale -a
Например:
$ locale -a
C
C.UTF-8
en_US.utf8
setlocale(LC_CTYPE, 'en_US.utf8');
public static function setUpBeforeClass()
{
setlocale(LC_CTYPE, 'en_US.utf8');
}
источник:
Я сделал один класс для работы со строками, а один из методов использует iconv.
При использовании phpunit в Windows iconv не может транслитерировать из-за проблем с языковым стандартом. Даже использование setlocale () в коде всегда приводит к провалу теста с использованием кода ниже.
/**
* @param $str Convert string to lowercase and replace special chars to equivalents ou remove its
* @return string
*/
public static function slugify($str)
{
$str = self::toUtf8($str); // Convert from any encoding to UTF-8
$str = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $str); // transliterate
$str = strtolower($str); // lowercase
return $str;
}
Модульный тест
public function testSlugfy()
{
// Basic String
$str = StringUtils::slugify($this->basicstring);
$this->assertEquals(strtolower($this->basicstring), $str, 'Basic String cannot be slugfied');
// Latin String
$str = StringUtils::slugify($this->latinstring);
$this->assertEquals(strtolower($this->basicstring), $str, 'Latin1 String cannot be slugfied');
// UTF-8 String
$str = StringUtils::slugify($str);
$this->assertEquals(strtolower($this->basicstring), $str, 'UTF8 String cannot be slugfied');
}
У меня нет проблем с моим приложением, но тест PHPUnit не работает с приведенным выше кодом.
Итак, чтобы пройти тест, я меняю функцию на
/**
* @param $str Convert string to lowercase and replace special chars to equivalents ou remove its
* @return string
*/
public static function slugify($str)
{
$string = self::toUtf8($str);
$string = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
if ($string != htmlentities($str, ENT_QUOTES, 'UTF-8')) { // iconv fails
$string = htmlentities($str, ENT_QUOTES, 'UTF-8');
$string = preg_replace('#&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);#i', '$1', $string);
// If need to leave only 0-9, a-z and A-Z
// $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
// $string = preg_replace(array('#[^0-9a-z]#i', '#[ -]+#'), ' ', $string);
$string = trim($string, ' -');
}
// lowercase
$str = strtolower($string);
return $str;
}
А в конструкторе класса Unit Test я создаю строки с другим подходом, чтобы избежать проблем с кодировкой файлов и проблемами языкового стандарта.
private $basicstring;
private $latinstring;
private $utf8string;
public function __construct()
{
// ASCII string
$this->basicstring = 'aeioucAEIOUC';
// To avoid troubles using command line in different locales
// the string used to create different charset is a plain HTML entities
// Using html_entity_decode to convert the
// string ãéìôüçÃÉìÔÜÇ
// into ãéìôüçÃÉìÔÜÇ in different charsets
$html_chars = 'ãéìôüçÃÉìÔÜÇ';
$this->utf8string = html_entity_decode($html_chars, ENT_HTML5, 'UTF-8');
$this->latinstring = html_entity_decode($html_chars, ENT_HTML5, 'ISO-8859-1');
parent::__construct();
}
Я также использую Symfony 4