Knocks/BackEnd/Knoks.Test.Integrations/Framework/ProcExecutorTests.cs

232 lines
8.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Knoks.Framework.DataAccess;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Xunit;
namespace Knoks.Test.Integrations.Framework
{
public class ProcExecutorTests : IDisposable
{
#region Static SQL Commantd
private const string TableName = "Test_Table_Executor";
private const string GetProcName = "Test_Proc_Get_Executor";
private const string SetProcName = "Test_Proc_Set_Executor";
private static string[] SqlCommands = new[] {
@"IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'Test_Proc_Get_Executor' AND TYPE = 'P')
DROP PROCEDURE [Test_Proc_Get_Executor];",
//-------------------------------------------------------------------------------------
@"IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'Test_Proc_Set_Executor' AND TYPE = 'P')
DROP PROCEDURE [Test_Proc_Set_Executor];",
//-------------------------------------------------------------------------------------
@"IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME='Test_Table_Executor' AND XTYPE = 'U')
DROP TABLE [Test_Table_Executor];",
//-------------------------------------------------------------------------------------
@"CREATE TABLE [Test_Table_Executor]
(
Id BIGINT NOT NULL IDENTITY(1,1),
Col1 BIGINT NOT NULL,
Col2 VARCHAR(50) NOT NULL,
Col3 NVARCHAR(50) NOT NULL,
Col4 DateTime2 NOT NULL
);",
//-------------------------------------------------------------------------------------
@"CREATE PROCEDURE [Test_Proc_Get_Executor]
@Id BIGINT = NULL
AS
SELECT * FROM [Test_Table_Executor] WHERE [Id] = ISNULL(@Id, [Id]);
RETURN 0",
//-------------------------------------------------------------------------------------
@"CREATE PROCEDURE [Test_Proc_Set_Executor]
@Col1 BIGINT,
@Col2 VARCHAR(50),
@Col3 NVARCHAR(50),
@Col4 DateTime2,
@Id BIGINT OUT
AS
INSERT INTO [Test_Table_Executor] VALUES (@Col1, @Col2, @Col3, @Col4);
SET @Id = SCOPE_IDENTITY()
RETURN 0"
};
static ProcExecutorTests()
{
for (var i = 0; i < SqlCommands.Length; i++)
{
SqlCommands[i] = Regex.Replace(SqlCommands[i], "Test_Table_Executor", TableName);
SqlCommands[i] = Regex.Replace(SqlCommands[i], "Test_Proc_Get_Executor", GetProcName);
SqlCommands[i] = Regex.Replace(SqlCommands[i], "Test_Proc_Set_Executor", SetProcName);
}
}
private static void SqlRunner(IEnumerable<string> sqls)
{
using (var con = new SqlConnection(Config.DefaultDbConnection))
{
con.Open();
foreach (var sql in sqls)
{
using (var cmd = new SqlCommand(string.Format(sql), con))
{
cmd.ExecuteNonQuery();
}
}
}
}
private static void InitializeDatabaseEntities()
{
SqlRunner(SqlCommands);
}
private static void DestroyDatabaseEntities()
{
SqlRunner(SqlCommands.Take(3));
}
#endregion
private ProcExecutor _executor;
public ProcExecutorTests()
{
SqlRunner(SqlCommands);
_executor = new ProcExecutor(Config.DbConnections, new Logger<ProcExecutor>(new LoggerFactory()));
}
public void Dispose()
{
SqlRunner(SqlCommands.Take(2));
}
private class TestRecord
{
public long Col1 { get; set; }
public string Col2 { get; set; }
public string Col3 { get; set; }
public DateTime Col4 { get; set; }
[ProcParamIgnore]
public string Col5 { get; set; } = "NotExistColumnInDb";
}
class TestRecordComparer : IEqualityComparer<TestRecord>
{
public static readonly TestRecordComparer Instance = new TestRecordComparer();
public bool Equals(TestRecord x, TestRecord y)
{
return
x.Col1 == y.Col1 &&
x.Col2 == y.Col2 &&
x.Col3 == y.Col3 &&
x.Col4 == y.Col4;
}
public int GetHashCode(TestRecord obj)
{
return obj.GetHashCode();
}
}
[Fact(DisplayName = "GeneralPassingTest")]
public async Task GeneralPassingTest()
{
var rowsExpected = new List<TestRecord>
{
new TestRecord { Col1 = 1, Col2 = "Text 2-1", Col3 = "Text 3-1", Col4 = DateTime.UtcNow },
new TestRecord { Col1 = 2, Col2 = "Text 2-2", Col3 = "Text 3-2", Col4 = DateTime.UtcNow },
new TestRecord { Col1 = 3, Col2 = "Text 2-3", Col3 = "Text 3-3", Col4 = DateTime.UtcNow },
new TestRecord { Col1 = 4, Col2 = "Text 2-4", Col3 = "Text 3-4", Col4 = DateTime.UtcNow },
new TestRecord { Col1 = 5, Col2 = "Text 2-5", Col3 = "Text 3-5", Col4 = DateTime.UtcNow }
};
var rowsActual = new List<TestRecord>();
foreach (var rowExpected in rowsExpected)
{
var dr = await _executor.Go(SetProcName, rowExpected);
rowsActual.Add((await _executor.Go(GetProcName, dr.OutputParams.First())).Тables[0][0].To<TestRecord>());
};
Assert.Equal(rowsExpected, rowsActual, TestRecordComparer.Instance);
}
[Fact(DisplayName = "ParamPassingTest")]
public async Task ParamsPassingTest()
{
var testRow = new TestRecord { Col1 = 1, Col2 = "Text 1", Col3 = "Text 1", Col4 = DateTime.UtcNow };
var rowsExpected = new List<TestRecord> { testRow, testRow, testRow, testRow };
var d = new Dictionary<string, object> { { "Col1", testRow.Col1 }, { "Col2", testRow.Col2 }, { "Col3", testRow.Col3 }, { "Col4", testRow.Col4 } };
var objects = new List<object> { testRow, d, d.ToArray(), d.ToList() };
var rowsActual = new List<TestRecord>();
foreach (var obj in objects)
{
var dr = await _executor.Go(SetProcName, obj);
rowsActual.Add((await _executor.Go(GetProcName, dr.OutputParams.First())).Тables[0][0].To<TestRecord>());
}
Assert.Equal(rowsExpected, rowsActual, TestRecordComparer.Instance);
}
[Fact(DisplayName = "MultiParamsPassingTest")]
public async Task MultiParamsPassingTest()
{
var rowsExpected = new TestRecord { Col1 = 1, Col2 = "Text 1", Col3 = "Text 1", Col4 = DateTime.UtcNow };
var dr = await _executor.Go(SetProcName, new { Col1 = rowsExpected.Col1, Col2 = rowsExpected.Col2 }, new { Col3 = rowsExpected.Col3, Col4 = rowsExpected.Col4 });
var rowsActual = (await _executor.Go(GetProcName, dr.OutputParams.First())).Тables[0][0].To<TestRecord>();
Assert.Equal(rowsExpected, rowsActual, TestRecordComparer.Instance);
}
[ProcParamIgnore]
private class IgnoreTestRecord
{
public long Col1 { get; set; }
public string Col2 { get; set; }
public string Col3 { get; set; }
public DateTime Col4 { get; set; }
}
[Fact(DisplayName = "Ignore record class")]
public async Task IgnoreRecordClass()
{
await Assert.ThrowsAsync<ArgumentException>(async () =>
{
await _executor.Go(SetProcName, new IgnoreTestRecord());
});
}
[Fact(DisplayName = "Ignore record KeyValuePair")]
public async Task IgnoreRecordKeyValuePair()
{
await Assert.ThrowsAsync<SqlException>(async () =>
{
await _executor.Go(SetProcName, new KeyValuePair<string, object>("key", new IgnoreTestRecord()));
});
}
[Fact(DisplayName = "Ignore records in Dictionary")]
public async Task IgnoreRecordDictionary()
{
await Assert.ThrowsAsync<SqlException>(async () =>
{
await _executor.Go(SetProcName, new Dictionary<string, object> { { "k1", new IgnoreTestRecord() }, { "k2", new IgnoreTestRecord() } });
});
}
}
}