@proGO

Страница 1495 из 1674
Dmitri
08.06.2018
08:07:33
либо в метод, либо в пакет, либо в структуры пакета

но это уже вкусовщина

и все зависит от того, что твой пакет делает

если пакет - неотъемлемая часть приложения, можно его и синглтонами накормить, и свои кастомные зависимости напихать, и вообще

Google
Dmitri
08.06.2018
08:09:07
если пакет - библиотека, планируемая для реюза, так делать, конечно, не стоит

Александр
08.06.2018
08:09:13
ладно спасибо - я убег

Dmitri
08.06.2018
08:09:16
чем меньше в ней зависимостей, тем лучше

удачи тебе

Artem
08.06.2018
08:13:09
для тестов надо везде юзать Dependency Injection
Как мне дб конектор замокать ибо он не подменяется на интерфейс ибо там в методе возвращается транзакция, а вернуть свою подменную транзакцию я не могу ?

Artem
08.06.2018
08:49:39
это уже будет не юнит, а интеграционка

FRD Official - Dmitriy
08.06.2018
08:51:40
Artem
08.06.2018
08:52:51
В интеграционке мне кейсы недоступности базы в разные моменты воссоздать тяжело, из серии начать транзакцию удалось, а коммит нет

FRD Official - Dmitriy
08.06.2018
09:01:10
Не тестируй в нем живость бд - не будет интеграционкой

Artem
08.06.2018
09:04:13
Кейсы аварийного поведения мне тяжело задавать в тестовой бд, а мне надо проверить что во в любом случае данные не будут утеряны

Dmitri
08.06.2018
09:15:35
есть мнение, что это концептуально слабовозможно... доказательства будут лежать больше в математической плоскости

Google
Dmitri
08.06.2018
09:17:15
как бы, юнит - это такая штука, которая проверяет корректность кода. Ну, т.е. проверяет, насколько это возможно, факт того, что код делает ровно то, что обещал в неаварийных условиях работы, т.е. проверка, если угодно, на "соответствие контракту"

в случае "уронить соединение посреди транзакции" вам никто и ничего гарантировать не сможет

ну и, собственно, достаточно странный подход

ваш код либо завершил транзакцию, т.е. получил гарантию сохранности/консистентности данных со стороны БД, либо не смог, т.е. получил гарантию отсутствия изменений с момента старта транзакции со стороны БД

случай обрыва связи посреди транзакции - это ровно второй случай, и он, если честно, со стороны приложения проверке не подлежит, не та область ответственности

Artem
08.06.2018
09:23:51
Ну мне надо проверить что в случае отказа базы, он в файл запишет данные которые затем можно будет восстановить. Сам клиент коннекта имеет возможность вернуть еррор при выполнение транзакции.

FRD Official - Dmitriy
08.06.2018
09:28:10
Dmitri
08.06.2018
09:29:50
Ну мне надо проверить что в случае отказа базы, он в файл запишет данные которые затем можно будет восстановить. Сам клиент коннекта имеет возможность вернуть еррор при выполнение транзакции.
соответственно, тестированию подлежат следующие кейсы: 1. коммит прошел - проверяем корректность записанных данных, 2. коммит не прошел - проверяем корректность записи на диск

для второго достаточно запустить ровно то же самое без наличия соединения с базой

а эмулировать дроп коннекта посредине - это уже патч бд-коннекта с отсутствием гарантии идентичности поведения патченного бд-коннекта и непатченного бд-коннекта

ну, т.е. ересь получается

Artem
08.06.2018
09:33:02
Ну попытка тестирования в лоб заключалась в

type dbSqlInterface interface { Begin() (transactionInterface, error) Exec(query string, args ...interface{}) (sql.Result, error) Ping() error SetConnMaxLifetime(duration time.Duration) } type transactionInterface interface { Exec(query string, args ...interface{}) (sql.Result, error) Rollback() error Commit() error }

Dmitri
08.06.2018
09:34:32
вы аппаратные проблемы все равно на уровне юнит-тестирования не смоделируете

а значит не стоит и пытаться

Artem
08.06.2018
09:35:21
я эмулирую различный возврат фунций, ошибка не ошибка

выше представленный интерфейс хорошо работает, проверяет то что надо, но реальный конект - Begin() (*sql.Tx, error)

и вот этот один шаг, до решения всех моих проблем, все навернул

хотя и *sql.Tx реализует transactionInterface

Google
Artem
08.06.2018
09:38:24
и тут момент, даже не о моке конкретно базы, а что если автор пакета не завязал возрат на интерфейс, тестирование может сильно усложнится

Dmitri
08.06.2018
09:43:22
дело в том, что тестировать проблему с БД между sql.Begin() и sql.Commit() смысла нет

если где-то между произошел дроп соединения с базой, sql.Commit() зафейлится

а все, что вы писали между - откатится

т.е. смысла тестировать ЭТО - нет

Artem
08.06.2018
09:45:28
Даже если так, я не могу подменить sql.Commit() и проверять ошибку только в нем

Dmitri
08.06.2018
09:45:46
на уровне вашего приложения все, что происходит между sql.Tx.Query() и получением *sql.Result - черный ящик

и зачем проверять в нем ошибку?

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

если вы, конечно, не пишете драйвер БД

Artem
08.06.2018
09:47:36
На уровне кода фунция, коммит имеет возможность вернуть ошибку

Artem
08.06.2018
09:47:59
-> значит этот кейс расматривается как поведение

Dmitri
08.06.2018
09:48:07
для того, чтобы она вернула ошибку, можно тупо не поднимать коннект к базе вообще

Artem
08.06.2018
09:48:43
тогда и пинг, и бегин вернут ошибку

Dmitri
08.06.2018
09:49:02
вы можете сделать реализацию интерфейса sql.Tx, которая будет на Commit возвращать тупо ошибку

а остальные - нет

Artem
08.06.2018
09:49:13
я сделал

Dmitri
08.06.2018
09:49:34
в ситуации дропа коннекта к базе вас интересует исключительно один фактор: коммит вернул ошибку

причем детали ошибки вас не интересуют, от слова "вообще"

Google
Artem
08.06.2018
09:49:52
все верно

посмотрите код выше, Begin() (*sql.Tx, error) а мне для подмены надо сделать Begin() (transactionInterface, error) *sql.Tx реализует transactionInterface

Dmitri
08.06.2018
09:50:36
ну так вот в чем вопрос: в чем суть юнит-тестирования

sql.Tx - интерфейс же?

Artem
08.06.2018
09:51:24
неа

// Tx is an in-progress database transaction. // // A transaction must end with a call to Commit or Rollback. // // After a call to Commit or Rollback, all operations on the // transaction fail with ErrTxDone. // // The statements prepared for a transaction by calling // the transaction's Prepare or Stmt methods are closed // by the call to Commit or Rollback. type Tx struct { db *DB

Dmitri
08.06.2018
09:51:55
не, структура, уговорил

Artem
08.06.2018
09:52:05
из .../go/1.10.1/libexec/src/database/sql/sql.go

Dmitri
08.06.2018
09:52:54
ну тогда нужно реализовывать sql-драйвер

Admin
ERROR: S client not available

Dmitri
08.06.2018
09:54:54
go-sql-driver реализовывает интерфейс же

Artem
08.06.2018
09:54:58
я всеравно же упрусь в контракт Begin() (*sql.Tx, error)

Dmitri
08.06.2018
09:56:27
неа

import( _ "github.com/lib/pq" )

а в lib/pq вот такая вещь: func init() { sql.Register("postgres", &Driver{}) }

а вот уже Driver реализовывает интерфейс

ща поищу, куда там можно вклиниться

https://golang.org/src/database/sql/doc.txt

Artem
08.06.2018
10:03:28
Буду где то там копать, спасибо

Dmitri
08.06.2018
10:04:28
https://golang.org/pkg/database/sql/driver/

Google
Dmitri
08.06.2018
10:04:50
во, вот тут написано defines interfaces to be implemented by database drivers as used by package sql

т.е. здесь интерфейсы для всего лоу-левела под sql

вооот же ОНО:

https://golang.org/pkg/database/sql/driver/#Tx

т.е. в драйвере есть driver.Tx, который интерфейс

а в момент sql.Register в сервис-провайдере регистрируется нужный тип

в момент db.Open - создается его инстанс, и дальше sql рулит пулом этих инстансов

а в sql.Tx в момент инициализации соединения суется реализация driver.Tx

они реализовывают один и тот же интерфейс, поэтому там просто подсовываются указатели на методы

Artem
08.06.2018
10:10:07
Я начинал с sql.DB как с входной точки

Dmitri
08.06.2018
10:10:10
т.е. для ваших особо изощренных тестирований - пишите драйвер)

а она юзает sql/driver.Driver под капотом

Artem
08.06.2018
10:11:20
Который умеет только Open(name string) (Conn, error) ?

FRD Official - Dmitriy
08.06.2018
10:11:27
Все украдено до нас https://github.com/DATA-DOG/go-sqlmock

Dmitri
08.06.2018
10:11:48
а этот Conn - это интерфейс

а скулю нужно рулить пулом этих соединений

Все украдено до нас https://github.com/DATA-DOG/go-sqlmock
верю, должна уже быть реализация этой прелести)

Artem
08.06.2018
10:12:44
Все украдено до нас https://github.com/DATA-DOG/go-sqlmock
это как раз паралельно ковыряю, но была надежда как то добить, то что уже сделано

FRD Official - Dmitriy
08.06.2018
10:13:15
Dmitri
08.06.2018
10:14:53
это как раз паралельно ковыряю, но была надежда как то добить, то что уже сделано
собственно, можно взять ЭТО, потом замутить свой тип sql.Tx с sql.Tx'ом унутре, и перекрытым методом Commit()///

Artem
08.06.2018
10:17:54
тут вот не до конца понял мы же упремся в func (m *testSql) Begin() (*sql.Tx, error) где не сможем вернуть - type testTransaction struct{ sql.Tx }

Dmitri
08.06.2018
10:19:41
а зачем тебе возвращать testTransaction?

Страница 1495 из 1674