DbConnection без Db с использованием набора данных в памяти (или аналогичного) в качестве источника - PullRequest
7 голосов
/ 25 марта 2009

Я пытаюсь провести модульное тестирование нескольких классов .NET, которые (по причинам хорошего дизайна) требуют, чтобы DbConnections выполнял свою работу. Для этих тестов у меня есть определенные данные в памяти, которые можно использовать в качестве входных данных для этих классов.

Эти данные в памяти могут быть легко выражены как DataTable (или DataSet, который содержит этот DataTable), но если бы другой класс был более подходящим, я мог бы использовать его.

Если бы я каким-то волшебным образом смог получить DbConnection, представляющий соединение с данными в памяти, я мог бы создать свои объекты, заставить их выполнять свои запросы к данным в памяти и гарантировать, что их выходные данные соответствуют ожиданиям , Есть ли какой-нибудь способ получить DbConnection для данных в памяти? У меня нет свободы устанавливать какое-либо дополнительное стороннее программное обеспечение, чтобы это произошло, и в идеале я не хочу касаться диск во время тестов.

Ответы [ 3 ]

6 голосов
/ 26 марта 2009

Вместо использования DbConnection вы можете использовать IDbConnection и высмеивать его? Мы делаем нечто подобное, передаем макет DataSet. DataSet.CreateDataReader возвращает DataTableReader, который наследуется от DbDataReader.

Мы обернули DbConnection в наш собственный интерфейс, подобный IDbConnection, к которому мы добавили метод ExecuteReader (), который возвращает класс, реализующий те же интерфейсы, что и DbDataReader. В нашем макете ExecuteReader просто возвращает то, что обслуживает DataSet.CreateDataReader.

Звучит как обход, но очень удобно создать DataSet с возможно большим количеством наборов результатов. Мы называем DataTables в честь хранимых процедур, для которых они представляют результаты, и наша модель IDbConnection выбирает правильный Datatable на основе процедуры, вызываемой клиентом. DataTable также реализует CreateDataReader, поэтому мы готовы идти.

3 голосов
/ 28 июля 2016

Подход, который я использовал, заключается в создании базы данных Sqlite в памяти. Это можно сделать, просто вставив пакет System.Data.SQLite.Core NuGet в свой проект модульного тестирования, вам не нужно устанавливать какое-либо программное обеспечение где-либо еще.

Хотя это звучит как действительно очевидная идея, только когда я посмотрел на тестовые модули Dapper, я решил сам использовать эту технику! См. Метод GetSqliteConnection в

https://github.com/StackExchange/dapper-dot-net/blob/bffb0972a076734145d92959dabbe48422d12922/Dapper.Tests/Tests.cs

Следует помнить одну вещь: если вы создаете sqlite db в памяти и создаете и заполняете таблицы, вам нужно быть осторожным, чтобы не закрыть соединение перед выполнением тестовых запросов, потому что открытие нового соединения в памяти будет Вы получите соединение с новой базой данных в памяти, , а не базой данных, которую вы только что тщательно подготовили для своих тестов! Для некоторых моих тестов я использую пользовательскую реализацию IDbConnection, которая держит соединение открытым, чтобы избежать этой ошибки - например,

https://github.com/ProductiveRage/SqlProxyAndReplay/blob/master/Tests/StaysOpenSqliteConnection.cs

0 голосов
/ 26 марта 2009

TypeMock? (Вы должны были бы 'установить' это все же).

Будьте осторожны, предполагая, что Data * может дать вам правильные приемы для тестирования - это довольно худший случай в целом. Но вы говорите «Хорошие дизайнерские причины», так что я уверен, что все это освещено: D

...