78 lines
4.7 KiB
C#
78 lines
4.7 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
|
||
namespace Kit.Helpers.SqlHelperAbstract
|
||
{
|
||
/// <summary>
|
||
/// Строка подключения для unit-тестов: единственный публичный вход в тестовое API (конвенция 1:1).
|
||
/// Фейк-транспорт (SqlHelperTest) — internal: недостижим из внешнего и прод-кода,
|
||
/// в том числе через new; тестирование репозиториев идёт только через этот интерфейс.
|
||
/// </summary>
|
||
public interface IConnectionStringTest : IConnectionString
|
||
{
|
||
/// <summary>Падает, если открытая заготовка не израсходована вызовом транспорта.</summary>
|
||
void VerifyAll();
|
||
|
||
/// <summary>Снапшоты всех запросов к транспорту, в порядке вызовов (ассерты снаружи).</summary>
|
||
IReadOnlyList<RequestParams> Requests { get; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Строка подключения для unit-тестов: вместо соединения с БД возвращает внутренний фейк-транспорт.
|
||
/// Один экземпляр на тест-метод, конвенция 1:1 (одна заготовка = один вызов транспорта = один метод репозитория):
|
||
/// var expArgs = new ConnectionString().PrepareExecute("req.requirement_select")
|
||
/// .AsStoredProcedure()
|
||
/// .AddParameter("p_doc_code", "TEST-DOC")
|
||
/// .AddParameter("p_rid", DBNull.Value)
|
||
/// .BuildParams();
|
||
/// var cs = new ConnectionStringTest(expArgs, _fxRequirementTable); // один DataTable = один курсор
|
||
/// var rows = new RequirementRepository(cs).SelectRequirements(filter);
|
||
/// cs.VerifyAll();
|
||
/// // дополнительные ассерты: cs.Requests — журнал вызовов транспорта.
|
||
/// Скалярный ответ (ExecuteScalar/NonQuery) — фабрика ConnectionStringTest.Scalar(expArgs, 1).
|
||
/// Заготовкаввввake_case, типизированные DataColumn — значения в CLR-типах,
|
||
/// которые вернул бы Npgsql (integer → int, bigint → long, boolean → bool, text → string,
|
||
/// timestamptz → DateTime); null-ячейка — DBNull.Value (NULL-строка LEFT JOIN).
|
||
/// Беззначная заявка параметра (только наличие, значение не сверяется) — маркер ParamExpect.Any.
|
||
/// </summary>
|
||
public class ConnectionStringTest : ConnectionString, IConnectionStringTest
|
||
{
|
||
private readonly SqlHelperTest _sqlHelper;
|
||
|
||
/// <summary>
|
||
/// Заготовка выборки: таблицы DataTable — по одной на курсор (курсор ↔ конвертер),
|
||
/// порядок таблиц = порядок курсоров функции БД; пустой результат — таблица с колонками без строк.
|
||
/// </summary>
|
||
public ConnectionStringTest(RequestParams requestParams, params DataTable[] resultTables)
|
||
: this(requestParams, resultTables, scalarResult: null)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// Заготовка скалярного ответа (ExecuteScalar; для ExecuteNonQuery результат не читается,
|
||
/// но заготовка обязана быть описана — конвенция «ответ обязан быть описан»).
|
||
/// </summary>
|
||
public static ConnectionStringTest Scalar(RequestParams requestParams, object scalarResult) =>
|
||
new(requestParams, Array.Empty<DataTable>(), scalarResult);
|
||
|
||
private ConnectionStringTest(RequestParams requestParams, DataTable[] resultTables, object? scalarResult)
|
||
{
|
||
_sqlHelper = new SqlHelperTest(requestParams, resultTables, scalarResult);
|
||
}
|
||
|
||
public override ISqlHelper GetSqlHelper() => _sqlHelper;
|
||
|
||
public void VerifyAll() => _sqlHelper.VerifyAll();
|
||
|
||
public IReadOnlyList<RequestParams> Requests => _sqlHelper.Requests;
|
||
}
|
||
|
||
/// <summary>Маркеры ожиданий параметров заготовки ConnectionStringTest.</summary>
|
||
public static class ParamExpect
|
||
{
|
||
/// <summary>Беззначная заявка: параметр обязан уйти в запрос, значение не сверяется.</summary>
|
||
public static readonly object Any = new();
|
||
}
|
||
}
|