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

StackOverflow https://stackoverflow.com/questions/683395

  •  22-08-2019
  •  | 
  •  

Вопрос

Я пытаюсь провести модульное тестирование нескольких .СЕТЕВЫЕ классы, которым (по веским причинам проектирования) требуются DbConnections для выполнения своей работы.Для этих тестов у меня есть определенные данные в памяти, которые я могу предоставить в качестве входных данных этим классам.

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

https://github.com/StackExchange/dapper-dot-net/blob/bffb0972a076734145d92959dabbe48422d12922/Dapper.Тесты/Tests.cs

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

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

TypeMock?(Однако вам нужно было бы его "установить").

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top