Регистрация  |  Вход

Как в тесте залезть в "труднодоступные" catchs?

Всем привет!

Готовлю большой класс с несколькими ДМЛ операциями к отправке в Прод.

Тест написан, но покрытие не впечатляющее - 82%.

Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.

И я не знаю как спровоцировать ДМЛ исключение - на объектах нет обязательных полей: вставляй, что хочешь - "жалко - нет".

Не знаю, что предпринять.

И по ходу возник еще вопрос:
На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте.
Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле.
Это правильно?

Всем привет!

Готовлю большой класс с несколькими ДМЛ операциями к отправке в Прод. 

Тест написан, но покрытие не впечатляющее - 82%. 

Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.

И я не знаю как спровоцировать ДМЛ исключение - на объектах нет обязательных полей: вставляй, что хочешь - "жалко - нет".

Не знаю, что предпринять.

И по ходу возник еще вопрос:
На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте.
Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле.
Это правильно?

1) Попробуй заинсертить объект без обязательных полей. Но смотря какой catch стоит...если нужного не будет - не поможет.

2) 82% - это очень неплохо...зачем еще больше?

1) Попробуй заинсертить объект без обязательных полей. Но смотря какой catch стоит...если нужного не будет - не поможет.

2) 82% - это очень неплохо...зачем еще больше?

Den Brown
И по ходу возник еще вопрос:
На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте.
Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле.
Это правильно?

Тут уже конкретно от задачи и бизнес-логики прыгать надо. Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...

[quote="Den Brown"]

И по ходу возник еще вопрос:
На объектах нет обязательных полей. Решил настраивать "обязательность" поля на лейауте.
Причина: чтобы при добавлении новых полей к существующим в проде каст объектам случайно не добавить новое обязательное (на уровне объекта) поле, которые положит код в Проде, работающий с данным объектом и ничего не подозревающий о том новом, обязательном поле.
Это правильно?[/quote]

Тут уже конкретно от задачи и бизнес-логики прыгать надо. Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...

Тест написан, но покрытие не впечатляющее - 82%.
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.

Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.

А по поводу "не заходит" в try/catch - если не получается воссоздать ситуацию для срабатывания исключени стоит задуматься, а нужно ли оно :). В Salesforce и так предусмотрен механизм отката всех изменений в базе в случае ошибки выполнения в пределах рабочего цикла.

Если все же ошибки нужно перехватывать и выводить пользователю вместо "экрана смерти Salesforce", то можно обернуть весь метод в try/catch и просто сделать обработку и вывод ошибки для всего блока. А для покрытия внутри блока сделать вызвать кастомную ошибку например по определенному параметру, который выставляется из теста.

[quote]Тест написан, но покрытие не впечатляющее - 82%. 
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.[/quote]

Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.

А по поводу "не заходит" в try/catch - если не получается воссоздать ситуацию для срабатывания исключени стоит задуматься, а нужно ли оно :). В Salesforce и так предусмотрен механизм отката всех изменений в базе в случае ошибки выполнения в пределах рабочего цикла.

Если все же ошибки нужно перехватывать и выводить пользователю вместо "экрана смерти Salesforce", то можно обернуть весь метод в try/catch и просто сделать обработку и вывод ошибки для всего блока. А для покрытия внутри блока сделать вызвать кастомную ошибку например по определенному параметру, который выставляется из теста.

Dmitry Shnyrev
Тест написан, но покрытие не впечатляющее - 82%.
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.

Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.


Ну не знаю у меня catch был больше чем try <!-- s:? --><img src="{SMILIES_PATH}/icon_e_confused.gif" alt=":?" title="Озадачен" /><!-- s:? --> .Ну есть несколько способов решить проблему,первый с которого я бы начал это проверил возможности метода addError() каждый sObject имеет этот метод который принимает Exception экземпляр или Стринг,насколько я помню addError работает только в контексте триггера,и возможно придется писать свой Exception класс для работы в контроллере.Второй способ попытатся про упдайтить не существующий объект или удалить.

[quote="Dmitry Shnyrev"][quote]Тест написан, но покрытие не впечатляющее - 82%. 
Причина - тест не заходит в catch-и которые стоят на вставках\апдейтах.[/quote]

Собственно для таких случаев и предусмотренно минимальное покрытие 75%. А 82% это очень даже хорошее покрытие для Salesforce.

[/quote]
Ну не знаю у меня catch был больше чем try <!-- s:? --><img src="{SMILIES_PATH}/icon_e_confused.gif" alt=":?" title="Озадачен" /><!-- s:? --> .Ну есть несколько способов решить проблему,первый с которого я бы начал это проверил возможности метода addError() каждый sObject имеет этот метод который принимает Exception экземпляр или Стринг,насколько я помню addError работает только в контексте триггера,и возможно придется писать свой Exception класс для работы в контроллере.Второй способ попытатся про упдайтить не существующий объект или удалить.

Art Vegas
Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...

у меня не было опыта деплоить на прод.

Получается, что, например, пришел новый inbound change set in Prod, а в нем новые обязательные поля к старым объектам.

И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?

[quote="Art Vegas"]
Новое поле не должно положить, так как если ты написал грамотно тесты, то оно тебе при деплое на прод сообщит...[/quote]

у меня не было опыта деплоить на прод.

Получается, что, например, пришел новый inbound change set in Prod, а в нем новые обязательные поля к старым объектам.

И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?

Den Brown
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?

Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.

По своему опыту скажу, у нас продакшен на одном проекте так разросься, что деплой ченж сетов достигал 8-9 часов. Потом, после обращения клиента в salesforce, оные ребята че-то подкрутили и стало нормальные 1-2 часа.

[quote="Den Brown"]
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?[/quote]

Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.

По своему опыту скажу, у нас продакшен на одном проекте так разросься, что деплой ченж сетов достигал 8-9 часов. Потом, после обращения клиента в salesforce, оные ребята че-то подкрутили и стало нормальные 1-2 часа.

Art Vegas
Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.

так вот зачем мы пишем все эти юнит-тесты.

не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.

[quote="Art Vegas"]

Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.

[/quote]

так вот зачем мы пишем все эти юнит-тесты.

не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.

Den Brown
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.

Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....

Как-то так.

[quote="Den Brown"]
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.[/quote]

Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....

Как-то так.

Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....

Это что-то интересное. Я думаю подробности будут не лишними. Ты говоришь что один пакет ссылается на другой (использует логику другого) но при этом его можно поставить на орг без этих зависимых пакетов. Я так понял что ты используешь динамическое связывание? При явной ссылке одного пакета на другой salesforce даже не даст поставить один пакет без другого.

"Юнит тесты имитировали работу стороннего пакета" - значит твой пакет видел что нет другого пакета, логику которого он использует, поэтому обращался к методам из твоих тестов?

Как-то так?

[quote]Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....[/quote]

Это что-то интересное. Я думаю подробности будут не лишними. Ты говоришь что один пакет ссылается на другой (использует логику другого) но при этом его можно поставить на орг без этих зависимых пакетов. Я так понял что ты используешь динамическое связывание? При явной ссылке одного пакета на другой salesforce даже не даст поставить один пакет без другого.

"Юнит тесты имитировали работу стороннего пакета" - значит твой пакет видел что нет другого пакета, логику которого он использует, поэтому обращался к методам из твоих тестов?

Как-то так?

Art Vegas
Den Brown
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.

Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....

Как-то так.

Как то не очень понятно можешь пояснить ?

[quote="Art Vegas"][quote="Den Brown"]
так вот зачем мы пишем все эти юнит-тесты.
не только (и вероятно не сколько) для текущего деплоймента, а для проверки на безопасность будущих, последующих изменений в системе.[/quote]

Мне однажды даже жизненеобходимо было написать юнит-тесты, потому, что другого варианта проверки кода не было. Суть была в том, что у меня был managed package, который зависел от других пакетов (зависел, т.е не включен...а логика была в других). Орг, на котором я разрабатывал не имел возможности проинсталировать другие пакеты. И спасло то, что я писал юнит-тесты, где имитировал работу стороннего пакета (передаваемые данные) мне в пакет....

Как-то так.[/quote]

Как то не очень понятно можешь пояснить ?

Art Vegas
Den Brown
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?

Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.


Почти так и происходит) да запускаются все тесты на продакшене,но в финальный расчет берутся только кастомные то есть если ты имешь manage packages на твоем продакшене тогда тесты тоже начнут отрабатывать,но в расчет для покрытия классов будут браться только кастомные. Я имел очень низкое покрытие для тестов из manage package но в финальные расчет брался только кастомный код то же самое относится и ошибкам. я бы сказал очень важная особенность.

[quote="Art Vegas"][quote="Den Brown"]
И в момент верификации система "крутит" не только те юнит-тесты, которые пришли с новым Сетом, а крутит ВСЕ юнит тесты в Проде, и некоторые из старых юнит тестов просто начнут падать из-за этого нового обязательного поля. И система сообщит об этом и не даст сделать деплой?[/quote]

Именно так и происходит). При валидации/деплое запускаются выполнения всех тестов на продакшене + тестов из ченж-сета.
[/quote]
Почти так  и происходит) да запускаются все тесты на продакшене,но в финальный расчет берутся только кастомные то есть если ты имешь manage packages на твоем продакшене тогда тесты тоже начнут отрабатывать,но в расчет для покрытия классов будут браться только кастомные. Я имел очень низкое покрытие для тестов из manage package но в финальные расчет брался только кастомный код то же самое относится и ошибкам.  я бы сказал очень важная особенность.

Sergey Prichepo
Как то не очень понятно можешь пояснить ?

Вся cуть вот в чем:
К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты

[quote="Sergey Prichepo"]

Как то не очень понятно можешь пояснить ?[/quote]

Вся cуть вот в чем:
К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты

Art Vegas
Sergey Prichepo
Как то не очень понятно можешь пояснить ?

Вся cуть вот в чем:
К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты


Это я понял) даже подход такой есть TDD.Сначало пишется тест а потом код на контроллер и триггер.Например у нас была проблема,я думаю что у некоторых она может возникнуть падали тест классы при создании пакета в чем дело очень долго никто не мог понять потому что если запускали по отдельности тесты все работало нормально.Оказалось что у нас был инсталирован зависимы пакет в дев орг.Дальше интереснее окзалось что там где в инсталиррованном пакете используются динамические запросы Database.query обязательно должна быть 30 versio api иначе созадать другой пакет где этот инсталирован не возможно.Пришлось пересоздавать пакет и занова исталировать.

[quote="Art Vegas"][quote="Sergey Prichepo"]

Как то не очень понятно можешь пояснить ?[/quote]

Вся cуть вот в чем:
К ответу Den зачем unit-test. Иногда нет возможности проверить свой код, как через апекс тесты[/quote]
Это я понял) даже подход такой есть TDD.Сначало пишется тест а потом код на контроллер и триггер.Например у нас была проблема,я думаю что у некоторых она может возникнуть падали тест классы при создании пакета в чем дело очень долго никто не мог понять потому что если запускали по отдельности тесты все работало нормально.Оказалось что у нас был инсталирован зависимы пакет в дев орг.Дальше интереснее окзалось что там где в инсталиррованном пакете используются динамические запросы Database.query обязательно должна быть 30 versio api иначе созадать другой пакет где этот инсталирован не возможно.Пришлось пересоздавать  пакет и занова исталировать.

У нас нечто похожее было. Правда я с пакетами мало работал. На тех проектах, где сейчас работаю - используются change set'ы. Правда порой тоже были странные проблемы с code coverage 60% на продакшене вместо 75% минимально положенных) И не задеплоить...было..и грязные хаки (a++ в тестах делали)...короче...потом все как-то само вернулось..оказалось проблемы были у SF.

У нас нечто похожее было. Правда я с пакетами мало работал. На тех проектах, где сейчас работаю - используются change set'ы. Правда порой тоже были странные проблемы с code coverage 60% на продакшене вместо 75% минимально положенных) И не задеплоить...было..и грязные хаки (a++ в тестах делали)...короче...потом все как-то само вернулось..оказалось проблемы были у SF.

К вопросу поднятому Дмитрием: а нужны ли ставить try-catch на абсолютно всех ДМЛ, даже в тех, в которых мы не ожидаем никаких проблем?

например где-то по ходу выполнения кода я делаю единичный (и по существу - второстепенный ) апдейт. Я не ожидаю в этой оперции никакого подвоха. Нужно ли брать этот апдейт в try-catch или оставить его "голяком" в коде - и если на нем возникнут когда-то проблемы - то пусть весь код падает - все равно нужно будет разбираться детально, что там внезапно произошло.

Не знаю как правильнее: to catch or not to catch каждый ДМЛ в коде?

К вопросу поднятому Дмитрием: а нужны ли ставить try-catch на абсолютно всех ДМЛ, даже в тех, в которых мы не ожидаем никаких проблем?

например где-то по ходу выполнения кода я делаю единичный (и по существу - второстепенный ) апдейт. Я не ожидаю в этой оперции никакого подвоха. Нужно ли брать этот апдейт в try-catch или оставить его "голяком" в коде - и если на нем возникнут когда-то проблемы - то пусть весь код падает - все равно нужно будет разбираться детально, что там внезапно произошло. 

Не знаю как правильнее:  to catch or not to catch каждый ДМЛ в коде?

Try/catch нужно если у тебя предусмотрен альтернативный обработчик ошибки.
если просто оборачивать каждую dml операцию чтобы вывести красиво ошибку то я думаю не стоит. Salesforce как CRM и там очень красиво показывает и обрабатывает ошибки.

Кстати в тему - когда пришел из PHP в SF то активно пользовался транзакциями собственно для которых и использовал try catch. Но особенность Salesforce полностью выкурила эту привычку. А именно Salesforce в случае ошибки (которую мы кстати не перехватили в try/catch) полностью откатывает все изменения в базе.

Так что я больше склоняюсь к тому чтобы не перехватывать, а наоборот как можно меньше использовать, а позволить SF самому разруливать ошибочные ситуации.

Try/catch нужно если у тебя предусмотрен альтернативный обработчик ошибки.
если просто оборачивать каждую dml операцию чтобы вывести красиво ошибку то я думаю не стоит. Salesforce как CRM и там очень красиво показывает и обрабатывает ошибки.

Кстати в тему - когда пришел из PHP в SF то активно пользовался транзакциями собственно для которых и использовал try catch. Но особенность Salesforce полностью выкурила эту привычку. А именно Salesforce в случае ошибки (которую мы кстати не перехватили в try/catch) полностью откатывает все изменения в базе.

Так что я больше склоняюсь к тому чтобы не перехватывать, а наоборот как можно меньше использовать, а позволить SF самому разруливать ошибочные ситуации.

Ну вот столкнулся с такой ситуацией.

контроллер который создает запись и может приатачить к ней 1 или 2 или 3 или 4 аттача.

каждый аттач индивидуально проверяется на наличие боди и имени в вставляется с индивидуальном трай-кетче.
и если вставка обломилась - в кетче (в зависимости от порядка атача, удаляются предидущие аттачи, головная запись). Т.е. там много строк в Кетчах.

и я не могу в тесте зайти в кетч.

как спровоцировать Insert исключение для Аттачмента? ПарентАйДи приписывается самим контроллером...

или придется делать один трай-кетч блок для всех Аттачей чтоб сократить кол-во недостижимых строк в кетчах...

мне логика в несколькими трай-кетчами больше нравится...

Ну вот столкнулся с такой ситуацией.

контроллер который создает запись и может приатачить к ней 1 или 2 или 3 или 4 аттача.

каждый аттач индивидуально проверяется на наличие боди и имени в вставляется с индивидуальном трай-кетче.
и если вставка обломилась - в кетче (в зависимости от порядка атача, удаляются предидущие аттачи, головная запись). Т.е. там много строк в Кетчах.

и я не могу  в тесте зайти в кетч.

как спровоцировать Insert исключение для Аттачмента? ПарентАйДи приписывается самим контроллером...

или придется  делать один трай-кетч блок для всех Аттачей чтоб сократить кол-во недостижимых строк в кетчах...

мне логика в несколькими трай-кетчами больше нравится...

Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

Alex Tsitsura
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

а что - идея.
значит есть класс со стат булевой переменной и методом который просто выбрасывает исключение.

в тесте первый прогон со булевой переменной false - все прогоняем как положено.

затем переводим булеву переменную в true - и второй прогон: траи выпадают в исключение при условии (Test.isRunningTest&&булеваПеременная) и код уходит в кетчи

[quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]

а что - идея.
значит есть класс со стат булевой переменной и методом который просто выбрасывает исключение.

в тесте первый прогон со булевой переменной false  - все прогоняем как положено.

затем переводим булеву переменную в true - и второй прогон: траи выпадают в исключение при условии (Test.isRunningTest&&булеваПеременная) и код уходит в кетчи

Alex Tsitsura
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

так и сделал - залез один за другим во все Кетчи. покрытие 100%

[quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]

так и сделал - залез один за другим во все Кетчи. покрытие 100%

Alex Tsitsura
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.

[quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.

Gres
Код не должен подстраиваться под тесты. Все должно быть наоборот.

звучит абсолютно правильно. но как в тесте спровоцировать ДМЛ исключение? изменить на-лету метадату, например сделав какое-то поле Required, а потом вернусь измененияч обратно? Хотя постойте-ка, а можно ли в коде, например, воткнуть в "телефооное" поле буквы? тогда код выпадет на ДМЛе и уйдет в Кетч...

[quote="Gres"] Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]

звучит абсолютно правильно. но как в тесте спровоцировать ДМЛ исключение? изменить на-лету метадату, например сделав какое-то поле Required, а потом вернусь измененияч обратно? Хотя постойте-ка, а можно ли в коде, например, воткнуть в "телефооное" поле буквы? тогда код выпадет на ДМЛе и уйдет в Кетч...

покрывать catch блоки в тестах не обязательно и даже не нужно. Для этого в Salesforce и предусмотрено 75% покрытия (25% можно потратить на catch блоки)
А то что при неправильных данных в поле у тебя доходит до exception DML Exception это жесть. А как же валидация входных данных и возвращение human readable error?
А если тебе ОЧЕНЬ надо проверить супер логику в catch блоке, то вынеси ее в отдельный класс в static метод а из catch блока вызывай этот метод 1 строкой кода. Особо на покрытии не потеряешь из-за одной строки, а static метод сможешь проверить без всяких страшных извращений с вызовом exceptoin.

PS. Хотя для спортивного интереса можешь и поизвращаться

покрывать catch блоки в тестах не обязательно и даже не нужно. Для этого в Salesforce и предусмотрено 75% покрытия (25% можно потратить на catch блоки)
А то что при неправильных данных в поле у тебя доходит до exception DML Exception это жесть. А как же валидация входных данных и возвращение human readable error?
А если тебе ОЧЕНЬ надо проверить супер логику в catch блоке, то вынеси ее в отдельный класс в static метод а из catch блока вызывай этот метод 1 строкой кода. Особо на покрытии не потеряешь из-за одной строки, а static метод сможешь проверить без всяких страшных извращений с вызовом exceptoin.

PS. Хотя для спортивного интереса можешь и поизвращаться :D 

Gres
Alex Tsitsura
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.

Абсолютно с Вами согласен, но иногда есть ситуации, какие нельзя воспроизвести в тесте.

[quote="Gres"][quote="Alex Tsitsura"]
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]
Абсолютно с Вами согласен, но иногда есть ситуации, какие нельзя воспроизвести в тесте.   

Alex Tsitsura
иногда есть ситуации, какие нельзя воспроизвести в тесте.

Если приходит такое понимание, то значит точно есть ошибка в проектировании.

[quote="Alex Tsitsura"]иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.

Поддержу Gres, не сталкивался с ситуациями, которые НЕЛЬЗЯ воспроизвести в тестах. Бывает это сложно сделать, особенно если код чужой и приходится заниматься реверс-инженерингом. Любой же код когда-нибудь вызывается. А если вызывается, то и тестами его можно покрыть. А если НЕ вызывается, то может он и не нужен в приложении

Поддержу Gres, не сталкивался с ситуациями, которые НЕЛЬЗЯ воспроизвести в тестах. Бывает это сложно сделать, особенно если код чужой и приходится заниматься реверс-инженерингом. Любой же код когда-нибудь вызывается. А если вызывается, то и тестами его можно покрыть. А если НЕ вызывается, то может он и не нужен в приложении :) 

Gres
Alex Tsitsura
иногда есть ситуации, какие нельзя воспроизвести в тесте.

Если приходит такое понимание, то значит точно есть ошибка в проектировании.

А если у нас делаются калаути, как мы можем зайти в catch блок?

[quote="Gres"][quote="Alex Tsitsura"]
иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.[/quote]
А если у нас делаются калаути, как мы можем зайти в catch блок?

Alex Tsitsura
ок?
Alex Tsitsura
Gres
Alex Tsitsura
иногда есть ситуации, какие нельзя воспроизвести в тесте.

Если приходит такое понимание, то значит точно есть ошибка в проектировании.

А если у нас делаются калаути, как мы можем зайти в catch блок?

Сгенерить ошибку в моке.

[quote="Alex Tsitsura"]ок?[/quote][quote="Alex Tsitsura"][quote="Gres"][quote="Alex Tsitsura"]
иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.[/quote]
А если у нас делаются калаути, как мы можем зайти в catch блок?[/quote]
Сгенерить ошибку в моке.

Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.

Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.

Gres, а в чем проблема использовать TDD.
Если посмотрим чисто с практической точки зрения.
Я конечно не начитанный малый, все познаю тупо из практики и может не понимаю что такое TDD.
Но если руководствоваться вот этим

Разработка через тестирование (англ. test-driven development, TDD) — техника разработки программного обеспечения, которая основывается на повторении очень коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется код, который позволит пройти тест, и под конец проводится рефакторинг нового кода к соответствующим стандартам.

то почему сложно реализовать эту методологию внутки Salesforce?
Типичный пример - писал недавно интеграцию и работал именно начиная с тестов. Пока не был готов реальный внешний сервис все данные подготавливались в тестах. И получалось что я сначала делал тесты, которые имитировали запросы и уже потом разрабатывал сами обработчики. Получилось очень классно. Как мне кажется это и есть TDD. Верно?

Gres, а в чем проблема использовать TDD.
Если посмотрим чисто с практической точки зрения. 
Я конечно не начитанный малый, все познаю тупо из практики и может не понимаю что такое TDD.
Но если руководствоваться вот этим 
[quote]Разработка через тестирование (англ. test-driven development, TDD) — техника разработки программного обеспечения, которая основывается на повторении очень коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется код, который позволит пройти тест, и под конец проводится рефакторинг нового кода к соответствующим стандартам.[/quote]
то почему сложно реализовать эту методологию внутки Salesforce?
Типичный пример - писал недавно интеграцию и работал именно начиная с тестов. Пока не был готов реальный внешний сервис все данные подготавливались в тестах. И получалось что я сначала делал тесты, которые имитировали запросы и уже потом разрабатывал сами обработчики. Получилось очень классно. Как мне кажется это и есть TDD. Верно?

Gres
Alex Tsitsura
ок?
Alex Tsitsura
Gres
Alex Tsitsura
иногда есть ситуации, какие нельзя воспроизвести в тесте.

Если приходит такое понимание, то значит точно есть ошибка в проектировании.

А если у нас делаются калаути, как мы можем зайти в catch блок?

Сгенерить ошибку в моке.

Да, об этом я не подумал(

[quote="Gres"][quote="Alex Tsitsura"]ок?[/quote][quote="Alex Tsitsura"][quote="Gres"][quote="Alex Tsitsura"]
иногда есть ситуации, какие нельзя воспроизвести в тесте.[/quote]
Если приходит такое понимание, то значит точно есть ошибка в проектировании.[/quote]
А если у нас делаются калаути, как мы можем зайти в catch блок?[/quote]
Сгенерить ошибку в моке.[/quote]
Да, об этом я не подумал(

Dmitry Shnyrev
Gres, а в чем проблема использовать TDD.

Dmitry Shnyrev
то почему сложно реализовать эту методологию внутки Salesforce?

Нужен удобный инструмент для моков, а также детерминированное время выполнения тестов.

Кст, могу посоветовать посмотреть - http://blog.byndyu.ru/2010/02/tdd_18.html

Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?

[quote="Dmitry Shnyrev"]Gres, а в чем проблема использовать TDD. [/quote]
[quote="Dmitry Shnyrev"]то почему сложно реализовать эту методологию внутки Salesforce? [/quote]
Нужен удобный инструмент для моков, а также детерминированное время выполнения тестов.

Кст, могу посоветовать посмотреть - http://blog.byndyu.ru/2010/02/tdd_18.html

Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?

Посмотрел видео. Отличное и понятное видео, несмотря на то что это для C#.
Пока понял что моки в C# предоставляют более продвинутые механизмы для контроля за выполнением кода - те же проверки выполнился ли метод и с какими параметрами. В Salesforce же мы в этом случае ограничены - можем опираться только на возвращаемые функцией данные для того чтобы проверить их с помощью system.assert...
Но все равно не увидел ничего такого что нельзя реализовать в Salesforce.
Принципы тестирования те же самые, просто реализация другая:
arrange - подготовка данных,
act - вызов функционала
assert - проверка результата.
Т.е. если я правильно понял, то в C# это дело происходит красиво внутри моков и мы просто можем контролировать их состояние, то в Salesforce наши тесты это и есть сами моки и мы сами делаем много ручной работы. Но имхо это только упрощает понимание и исключает лишний слой абстракции

Gres
Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?

В последнем случае что я описывал, да, именно сначала тесты и контроль результата, а потом уже реализация метода - прямо так как в видео.

Но в большинстве случаев мой принцип разработки получается не по феншую TDD, но его принципам. Дело в том что я в разработке никогда не проверяю функционал с помощью браузера (если он чуть сложнее простой странички). Т.е. критерием работы кода является именно тест. Я начинаю писать какой-то метод, когда код более менее сформирован (но не разу не запущен) пишу сразу тест и начинаю запускать тест и смотреть на результаты работы метода. Только после того как тест прошел и все user cases протестированы (в том числе искючительные ситуации) уже иду в браузер и наблюдаю идеально работающую страницу.
PS. Хотя, да, что-то я погорячился это нифига не TDD, а я просто описал стандартную разработку логики с тестами Все-таки TDD - именно разработка через тестирование и все начинается с тестов !!!

Посмотрел видео. Отличное и понятное видео, несмотря на то что это для C#.
Пока понял что моки в C# предоставляют более продвинутые механизмы для контроля за выполнением кода - те же проверки выполнился ли метод и с какими параметрами. В Salesforce же мы в этом случае ограничены - можем опираться только на возвращаемые функцией данные для того чтобы проверить их с помощью system.assert...
Но все равно не увидел ничего такого что нельзя реализовать в Salesforce.
Принципы тестирования те же самые, просто реализация другая:
arrange - подготовка данных,
act - вызов функционала
assert - проверка результата.
Т.е. если я правильно понял, то в C# это дело происходит красиво внутри моков и мы просто можем контролировать их состояние, то в Salesforce наши тесты это и есть сами моки и мы сами делаем много ручной работы. Но имхо это только упрощает понимание и исключает лишний слой абстракции :) 

[quote="Gres"]Т.е. ты сначала писал тесты, на методы без реализации, а потом релизовывал их так, чтобы тесты проходили?[/quote]
В последнем случае что я описывал, да, именно сначала тесты и контроль результата, а потом уже реализация метода - прямо так как в видео.

[i]Но в большинстве случаев мой принцип разработки получается не по феншую TDD, но его принципам. Дело в том что я в разработке никогда не проверяю функционал с помощью браузера (если он чуть сложнее простой странички). Т.е. критерием работы кода является именно тест. Я начинаю писать какой-то метод, когда код более менее сформирован (но не разу не запущен) пишу сразу тест и начинаю запускать тест и смотреть на результаты работы метода. Только после того как тест прошел и все user cases протестированы (в том числе искючительные ситуации) уже иду в браузер и наблюдаю идеально работающую страницу.
PS. Хотя, да, что-то я погорячился :) это нифига не TDD, а я просто описал стандартную разработку логики с тестами :) Все-таки TDD - именно разработка через тестирование и все начинается с тестов !!![/i]

Dmitry Shnyrev
Но все равно не увидел ничего такого что нельзя реализовать в Salesforce.

Я не говорил, что нельзя что-то сделать.
Gres
Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.

Просто это не совсем удобно.
Различные тестовые объекты - http://habrahabr.ru/post/116372/

[quote="Dmitry Shnyrev"]Но все равно не увидел ничего такого что нельзя реализовать в Salesforce. [/quote]
Я не говорил, что нельзя что-то сделать.
[quote="Gres"]Я помню, что кто-то тут ратовал за TDD, просто интересно, как в рамках данной платформы он реализует эту методологию.[/quote]
Просто это не совсем удобно.
Различные тестовые объекты - http://habrahabr.ru/post/116372/

Dmitry Shnyrev
Но имхо это только упрощает понимание и исключает лишний слой абстракции

Зря ты не любишь абстракции (:

[quote="Dmitry Shnyrev"]Но имхо это только упрощает понимание и исключает лишний слой абстракции [/quote]
Зря ты не любишь абстракции (:

Кстати, первый раз видел исходники на C# - красиво очень напоминает Salesforce. Особенно понравилась структура проекта - сразу выделены BusinessLogic, Domains - сразу намекает на правильное разделение кода по слоям.

Кстати, первый раз видел исходники на C# - красиво :) очень напоминает Salesforce. Особенно понравилась структура проекта - сразу выделены BusinessLogic, Domains - сразу намекает на правильное разделение кода по слоям.

Dmitry Shnyrev
Кстати, первый раз видел исходники на C# - красиво

Попробуй, это еще и вкусно, и удобное, и приятно.

[quote="Dmitry Shnyrev"]Кстати, первый раз видел исходники на C# - красиво [/quote]
Попробуй, это еще и вкусно, и удобное, и приятно.

Gres
Зря ты не любишь абстракции (:

Вернее сказать у меня к ним двоякое отношение - с одной стороны абстракции позволяют уменьшить сложность и упростить разработку. А с другой стороны это добавляет "магию", которой надо владеть. С этой точки зрения assembler считаю идеальным языком потому что там надо знать только команды процессора, регистры и структуру памяти, что можно уместить наверное на лист формата А4 (это конечно в упрощенном виде для примера). Весь процесс как на ладони. Но конечно я бы не стал на нем программировать, потому что это ОЧЕНЬ долго.
А вот абстракции надо знать чтобы уметь их варить. Вот типичный пример с этими моками. Я не знаю что ты под ними подразумеваешь, а могу лишь догадываться, потому что ты их, наверное, принес с собой из C#, а я тесты писал только под Salesforce. Может мы вообще говорим о разном, пытаясь перетянуть одеяло на свою сторону. А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?

[quote="Gres"]Зря ты не любишь абстракции (:[/quote]
Вернее сказать у меня к ним двоякое отношение - с одной стороны абстракции позволяют уменьшить сложность и упростить разработку. А с другой стороны это добавляет "магию", которой надо владеть. С этой точки зрения assembler считаю идеальным языком :D потому что там надо знать только команды процессора, регистры и структуру памяти, что можно уместить наверное на лист формата А4 (это конечно в упрощенном виде для примера). Весь процесс как на ладони. Но конечно я бы не стал на нем программировать, потому что это ОЧЕНЬ долго. 
А вот абстракции надо знать чтобы уметь их варить. Вот типичный пример с этими моками. Я не знаю что ты под ними подразумеваешь, а могу лишь догадываться, потому что ты их, наверное, принес с собой из C#, а я тесты писал только под Salesforce. Может мы вообще говорим о разном, пытаясь перетянуть одеяло на свою сторону. А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?

Dmitry Shnyrev
Я не знаю что ты под ними подразумеваешь

Выше ссылка на примерное описание различных тестовых объектов.
Кст, вот такая штука есть, но она мне не оч нравится - https://github.com/financialforcedev/fflib-apex-mocks

[quote="Dmitry Shnyrev"]Я не знаю что ты под ними подразумеваешь[/quote]
Выше ссылка на примерное описание различных тестовых объектов.
Кст, вот такая штука есть, но она мне не оч нравится - https://github.com/financialforcedev/fflib-apex-mocks

Gres
Попробуй, это еще и вкусно, и удобное, и приятно.

Возможно, но пока оставлю на будущее. Думаю что мой мозг взорвется, если я туда еще c# начну пихать.

[quote="Gres"]Попробуй, это еще и вкусно, и удобное, и приятно.[/quote]
Возможно, но пока оставлю на будущее. Думаю что мой мозг взорвется, если я туда еще c# начну пихать.

Dmitry Shnyrev
А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?

Зачем кто-то главный. Все равно все останутся при своем мнении.

[quote="Dmitry Shnyrev"]А если сейчас придет Wilder, то у него вообще окажется своя реализация моков под Salesforce и кто-тогда будет главным?[/quote]
Зачем кто-то главный. Все равно все останутся при своем мнении.

Gres
Зачем кто-то главный. Все равно все останутся при своем мнении.

А если работать в команде? Что из этого получится?

[quote="Gres"]Зачем кто-то главный. Все равно все останутся при своем мнении.[/quote]
А если работать в команде? Что из этого получится?

Gres
Просто это не совсем удобно.
Различные тестовые объекты - http://habrahabr.ru/post/116372/

С одной стороны статья немного прояснила тему тестирования, но с другой еще больше вопросов появилось:

Внешняя зависимость — это объект, с которым взаимодействует код и над которым нет прямого контроля. Для ликвидации внешних зависимостей в модульных тестах используются тестовые объекты, например такие как stubs (заглушки).

Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод:
— mock object (мок-объект), очень похож на тестовый шпион, однако не записывает последовательность вызовов с переданными параметрами для последующей проверки, а может сам выкидывать исключения при некорректно переданных данных. Т.е. именно мок-объект проверяет корректность поведения тестируемого объекта.

Млин, эта теория только еще больше запутывает.
Gres, проясни плиз. Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся? Как это квалифицировать?

[quote="Gres"]Просто это не совсем удобно. 
Различные тестовые объекты - http://habrahabr.ru/post/116372/[/quote]
С одной стороны статья немного прояснила тему тестирования, но с другой еще больше вопросов появилось:

[quote]Внешняя зависимость — это объект, с которым взаимодействует код и над которым нет прямого контроля. Для ликвидации внешних зависимостей в модульных тестах используются тестовые объекты, например такие как stubs (заглушки).[/quote]
Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод:
[quote]— mock object (мок-объект), очень похож на тестовый шпион, однако не записывает последовательность вызовов с переданными параметрами для последующей проверки, а может сам выкидывать исключения при некорректно переданных данных. Т.е. именно мок-объект проверяет корректность поведения тестируемого объекта.[/quote]
Млин, эта теория только еще больше запутывает.
Gres, проясни плиз. Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся? Как это квалифицировать?

Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.

Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.

Dmitry Shnyrev
А если работать в команде? Что из этого получится?

В команде должны быть определенные стандарты, которые известны всем и всех их поддерживают.

[quote="Dmitry Shnyrev"]А если работать в команде? Что из этого получится?[/quote]
В команде должны быть определенные стандарты, которые известны всем и всех их поддерживают.

Dmitry Shnyrev
Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод:

Считается, что объекты типа mock содержат в себе некое поведение.

[quote="Dmitry Shnyrev"]Получается что Mock объект - эта заглушка(одна из пяти разновидностей), которая передается в метод: [/quote]
Считается, что объекты типа mock содержат в себе некое поведение.

Dmitry Shnyrev
Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся?

Ну тесты, это тесты, а тут мы говорим про разлизные объекты для тестов.
В СФ мы в основном использует стабы.

[quote="Dmitry Shnyrev"]Если взять простые стандартные тесты в Salesforce и положить их на эту статью, то чем мы тогда занимаемся?[/quote]
Ну тесты, это тесты, а тут мы говорим про разлизные объекты для тестов.
В СФ мы в основном использует стабы.

Dmitry Shnyrev
Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.

Могу посоветовать The Art of Unit Testing - http://artofunittesting.com/

[quote="Dmitry Shnyrev"]Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D. [/quote]
Могу посоветовать The Art of Unit Testing - http://artofunittesting.com/

Dmitry Shnyrev
Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D.

Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.

[quote="Dmitry Shnyrev"]Короче, могу теперь точно сказать, что про тестирование я нихрена не знаю :D. [/quote]
Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.

Gres
Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.

Ну, незнание многих теоретических тем, это парит меня меньше всего . Знание практических аспектов webdev, я уверен, перекрывает этот скромный недостаток .
Парит то, что мой старый уже мозг отказывается воспринимать английский язык и продавать свои навыки. Вот это косяк.

[quote="Gres"]Да не парься, ты же не на собеседовании. Главное, чтобы твой код хорошо работал.[/quote]
Ну, незнание многих теоретических тем, это парит меня меньше всего :) . Знание практических аспектов webdev, я уверен, перекрывает этот скромный недостаток :) . 
Парит то, что мой старый уже мозг отказывается воспринимать английский язык и продавать свои навыки. Вот это косяк.

сопутствующий вопрос:

всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...

сопутствующий вопрос: 

всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...

Den Brown
сопутствующий вопрос:

всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...


У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)
Соответственно, есть всего 3 конструкции на весь проект.

[quote="Den Brown"]сопутствующий вопрос: 

всегда ли вы берете DML операцию в трай-кетч (в контроллерах к примеру) или даете самому СФ "обработать" исключительную ситуацию с DML? я это к тому, что может все эти мои Кетчи и не нужны вовсе...[/quote]
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)
Соответственно, есть всего 3 конструкции на весь проект.

Gres
IDatabase

Ну и ты доволен своей реализацией, особенно если нужно работать с sObject ? как насчет Upsert ?

[quote="Gres"]IDatabase[/quote]

Ну и ты доволен своей реализацией, особенно если нужно работать с sObject ? как насчет Upsert ?

wilder
Ну и ты доволен своей реализацией, особенно если нужно работать с sObject ?

Доволен, в IDatabase как раз sObject.
wilder
как насчет Upsert ?

Если он необходим реализуется в *DAO.

[quote="wilder"]Ну и ты доволен своей реализацией, особенно если нужно работать с sObject ?[/quote]
Доволен, в IDatabase как раз sObject.
[quote="wilder"]как насчет Upsert ?[/quote]
Если он необходим реализуется в *DAO.

Я все жду пока они доделают нормальную реализацию апсерта.

Я все жду пока они доделают нормальную реализацию апсерта.

Gres
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)

Получается, что вы создали для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??

[quote="Gres"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete) [/quote]

Получается, что вы создали  для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??

Den Brown
Gres
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)

Получается, что вы создали для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??


И не только для DML, а так да, правильно.

[quote="Den Brown"][quote="Gres"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete) [/quote]

Получается, что вы создали  для ДМЛ оперций свои собственные классы, с блекджеком и шл... и кастомной обработкой исключений??[/quote]
И не только для DML, а так да, правильно.

Den Brown
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)

А где можно узнать поподробней об этом для SF?

[quote="Den Brown"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)[/quote]
А где можно узнать поподробней об этом для SF?

DevNull
Den Brown
У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)

А где можно узнать поподробней об этом для SF?

Можешь просто прочитать про паттерны Data Access Object и Repository

[quote="DevNull"][quote="Den Brown"]У меня все DML в *DAO классах, которые используют реализацию IDatabase (insert, update, delete)[/quote]
А где можно узнать поподробней об этом для SF?[/quote]
Можешь просто прочитать про паттерны Data Access Object и Repository

Gres
Alex Tsitsura
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.

А как быть, если необходимо отключить триггер в тестах?

[quote="Gres"][quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]

А как быть, если необходимо отключить триггер в тестах?

ogoblin
Gres
Alex Tsitsura
Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.

Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.

А как быть, если необходимо отключить триггер в тестах?


Для отключения триггера используются кастом сеттинги.

[quote="ogoblin"][quote="Gres"][quote="Alex Tsitsura"]Я для таких ситуаций написал тест хелпер и метод в ньом ThrowExceptionIfTesting которий смотрит на Test.isRunningTest и на статическую булевую переменую, которой можно контролировать в каких ситуациях вибрасивать ексепшен. И етот метод пишу try блоке.[/quote]
Так делать в принципе не правильно. Код не должен подстраиваться под тесты. Все должно быть наоборот.[/quote]

А как быть, если необходимо отключить триггер в тестах?[/quote]
Для отключения триггера используются кастом сеттинги.

Gres
Для отключения триггера используются кастом сеттинги.

даю свой +1 за этот метод. Отличное кстати решение - отключение функционала по настройкам в custom settings.

[quote="Gres"]Для отключения триггера используются кастом сеттинги.[/quote]
даю свой +1 за этот метод. Отличное кстати решение - отключение функционала по настройкам в custom settings.

Возможно вы и правы оба. Только в таком случае не вижу разницы, что проверять - переменную в триггере или сеттинги.
Задача была до горя простая. Речь о тест-юните в пакете.
1. Отключить триггер.
2. Залить старые данные.
3. Проверить конвертацию.
Эта вся муть выполняется после установки пакета в процессе тестов.

Возможно вы и правы оба. Только в таком случае не вижу разницы, что проверять - переменную в триггере или сеттинги.
Задача была до горя простая. Речь о тест-юните в пакете. 
1. Отключить триггер.
2. Залить старые данные.
3. Проверить конвертацию.
Эта вся муть выполняется после установки пакета в процессе тестов.