
Sergey
02.03.2017
21:05:14
у нас с монги все запросы уехали на эластик. потому что монга не выдерживает

Daniel
03.03.2017
05:48:19

Andrew
03.03.2017
06:25:51
потому что ты приложение полностью загружаешь
скорее это даже не интеграционное а функциональное

Google

Sergey
03.03.2017
07:02:47

Дмитрий
03.03.2017
07:03:09
Ребята помогите найти ошибку
Пробую писать логи с помощью monolog
Если делаю так
$log = new Logger('conversion');
$log->pushHandler(new StreamHandler('log.log', Logger::INFO));
$log->error("Заявка $num " . $data['period'] . "не выполнена");
то все работает, лог пишется
Пытаюсь сделать чтобы все настройки хранились в конфиге
в config.yml
monolog:
handlers:
conversion:
type: stream
path: "%kernel.logs_dir%/conversion.log"
level: info
channels: conversion
в service.yml
monolog_web_processor:
class: Symfony\Bridge\Monolog\Logger
tags:
- { name: monolog.logger, channel: conversion }
сообщение не пишется в файл, а ввыводится в консоле (консольная команды выполняется)

Sergey
03.03.2017
07:03:14
ну и в приведенном примере бесполезный юнит тест)
лучше написать полноценный интеграционный тест с базой данных и ловить исключение
моки это весело, но конкретно тут я не вижу осбо от них профита

Andrew
03.03.2017
07:05:44
юнит тестом у меня его язык не поворачивается назвать, дергается все приложение, собирается кеш и так далее
вообще есть чудная вещь CommandTester в симфе

Sergey
03.03.2017
07:06:33
в целом - это юнит тест
так как он проверят один юнит - запускалку команд

Дмитрий
03.03.2017
07:12:50
ребята может кто-то подскажет по моему вопросу чуть выше

Sergey
03.03.2017
08:02:09
привет, подскажите как решить такую проблему. Есть сущность Product, есть класс который эту сущность сохраняет, внутри доктрина $em->persist($product);$em->flush(); Есть так же импорт товаров, в нем соответственно я не могу использовать класс для сохранения так как в импорте пачками persist и только потом flush. Получается что два разных места которые делают одно и тоже, сохраняют товар. Но код разный, а хочется сохранять одним сервисом везде. Как такое правильно разрулить архитектурно?

Sergey
03.03.2017
08:02:40
никогда не делай flush в сервисах

Google

Sergey
03.03.2017
08:02:46
ну или у тебя есть сервис который делает flush

Sergey
03.03.2017
08:04:13
то есть всегда нужно будет использовать два сервиса?

Sergey
03.03.2017
08:04:30
то есть всегда надо делать flush там где у тебя граница бизнес транзакции
контроллер например
или если у тебя есть циклик где надо пакетную обработку делать
то после каждой итерации или после части итераций

Sergey
03.03.2017
08:05:25
понял, спасибо!

Sergey
03.03.2017
08:05:52
ну и еще - ты же вкурсе что для "обновления" тебе не надо делать persist?

Sergey
03.03.2017
08:06:16
да)

Sergey
03.03.2017
08:08:28
может быть когда-нибудь в doctrine добавят метод save который минует unit-of-work
тогда можно будет уже чуть по другому делать

Sergey
03.03.2017
08:43:46
+ зарегать это канал еще нужно


Дмитрий
03.03.2017
10:35:56

Rodion
03.03.2017
10:36:41
прописать в конфиге новый поток

Sergey
03.03.2017
10:36:45
monolog:
channels: ['foo', 'bar']
и вместо @logger юзать @monolog.logger.foo
удобно кстати с разными каналами

Дмитрий
03.03.2017
10:48:43
может и удобно. но что-то не получается :)

Google

Daniel
03.03.2017
11:16:25
И как тут база данных завязана? :(

Sergey
03.03.2017
11:17:08

Дмитрий
03.03.2017
11:17:38
скорее всего нет раз файл не пишется

Sergey
03.03.2017
11:20:19
покажи конфиг сервиса где ты инжектишь логгер

Дмитрий
03.03.2017
11:21:04
monolog_web_processor:
class: Symfony\Bridge\Monolog\Logger
tags:
- { name: monolog.logger.conversion, channel: conversion }

Sergey
03.03.2017
11:21:20
так это процессор


Sergey
03.03.2017
11:40:25
@Enleur Спасибо, за комментарий! @rodneyspn Спасибо за совет. Как я понял вы не против моего небольшого сообщения.
Нам нужны на проект один PHP разработчик с хорошими знаниями symfony и/или Zend Проект логистического характера, система автоматизации. Проект не быстрый соответственно занятость гарантируем на несколько месяцев вперёд точно. Full-time не подразумеваем, 3-4 часа в день - норм.
Оплата достойная, проект российский, платим по средне-российской ставке для удалённых исполнителей (800-1000 рублей в час). Есть много иностранных проектов там платим больше, но это про будущее.
Условия:
1. Работа удалённая и график свободный(есть правда некоторые периоды времени каждый день когда Вы должны быть на связи)
2. Работа сдельная по оговорённой ставке
3. Все задачи проходят через Redmine с крайне подробным описанием и для всего у нас есть регламент.
4. Наши клиенты это крупные компании(Ростелеком, Гонка Героев, Водоканал, Международный Юридический Форум, Пулково ...), мы не запрещаем Вам рассказывать, что это сделали Вы =)
Контакты либо через почту m@mobecan.com либо тут в личку. В сообщении прошу указать портфолио.


Sergey
03.03.2017
11:41:34
только symfony, а не symphony)

Sergey
03.03.2017
11:43:07
@Enleur Спасибо =) Привычка

Дмитрий
03.03.2017
11:56:02

Sergey
03.03.2017
11:57:06
это ты делаешь процессор для конкретного канала типа
monolog.processor.uid:
class: Monolog\Processor\UidProcessor
tags:
- { name: monolog.processor, method: __invoke, channel: "foo" }

Sergey
03.03.2017
11:57:24
а тебе нужно именно писать в нужный канал

Sergey
03.03.2017
13:19:05
а в юнитах - это совсем другой разговор

Daniel
03.03.2017
13:19:34
А почему этот тест бесполезен?
Разве эту вещь не надо было тестировать?

Sergey
03.03.2017
13:20:10
абстрактный класс тестировать нужно в принципе только если он предназначен для чьего-то еще расширения

Sergey
03.03.2017
13:20:30

Daniel
03.03.2017
13:20:42
А он для этого и предназначен :(

Sergey
03.03.2017
13:20:43
когда у тебя тест полностью из моков состоит - он дублирует реализацию

Google

Daniel
03.03.2017
13:21:18
Ну там тестируется раннер, реализация раннера же не замочена :(

Sergey
03.03.2017
13:21:51

Daniel
03.03.2017
13:22:20
Тогда от обратного
когда моки используются?

Sergey
03.03.2017
13:22:51
когда нужна верификация вызовов

Sergey
03.03.2017
13:22:57
нет

Daniel
03.03.2017
13:23:01
А у меня не та ситуация?
Так-с

Admin
ERROR: S client not available

Daniel
03.03.2017
13:23:06
Я путаюся

Sergey
03.03.2017
13:23:08
когда надо проверить взаимодействие тестируемого объекта с внешним миром

Sergey
03.03.2017
13:23:24
ну верификация

Sergey
03.03.2017
13:24:07
НО!
если у тебя тестируемый код тупо вызывает другие штуки
нет логики
то тогда с моками ты попадешь в такую беду что у тебя в тестах полностью будет дублироваться кто что вызывает
и вот такой тест надо удалить и написать один интеграционный который пройдет по всем вызовам

Sergey
03.03.2017
13:25:22
ну хзхз, проще юнит
чем поднимать целый интеграционный для проверки

Sergey
03.03.2017
13:25:38

Google

Sergey
03.03.2017
13:25:46
ты поправишь реализацию - тебе придется править тесты
править моки

Sergey
03.03.2017
13:25:51
проверяет что вызываются зависимости
че это моки править?

Sergey
03.03.2017
13:26:10
ну блин
ты поменял порядок вызова методов, или метод начал в цикле вызываться

Sergey
03.03.2017
13:26:29
у тебя есть сервис который должен сделать A -> B -> C и вернуть результат C

Sergey
03.03.2017
13:26:43

Sergey
03.03.2017
13:26:48
фасад

Sergey
03.03.2017
13:27:23
function foo($data) {
$tmp = $this->a->doStuff($data);
$tmp = $this->b->doStuff($data);
return $this->c->doStuff($data);
}
вот так да?
такое юнит тестами бесполезно тестировать потому что ты не сможешь проверить поведение
а a, b и c и так покрыты юнит тестами
потому все что мы можем сделать - проверить что все в сборке работает

Sergey
03.03.2017
13:28:17
ну скажем
function($data){
$result = $this->a->do($data);
$result = $this->b->do($result);
return $this->c->do($result);
}

Sergey
03.03.2017
13:28:25
и вот для этого пишем один маленький интеграционный тест с одним позитивным тест кейсом

Sergey
03.03.2017
13:28:31
и если ты поменяешь вызовы местами в логике, то у тебя уже будет некорректная логика

Sergey
03.03.2017
13:28:36
1 интеграционный тест на 3 набора юнит тестов
как по мне все вполне в терминах 10% интеграционных тестов

Sergey
03.03.2017
13:31:00
1 интеграционный тест на 3 набора юнит тестов
а если сложно его поднимать? давай для примера возьмем вызов апи какого-то
сервис A у нас отвечает за преобразование $data в запрос
сервис B за отправку запроса на внешний сервис
сервис C разбирает то что верунл сервис и возвращает DTO
чтобы такое проверить полностью тебе нужно замокать эндпоинт на B, подобрать данные для $data и проверить то что вернул C. хотя все это уже протестировано, но по отдельным компонентам
и задача этого сервиса без логики именно спрятать все эти вызовы от юзера