Skip to content

Commit d474e71

Browse files
authored
Merge pull request #261 from ckadluba/refactoring-cleanup-tests
Added SqlConnectionFactory and added/adapted unit tests.
2 parents 3a8e36f + 33b923f commit d474e71

File tree

12 files changed

+161
-36
lines changed

12 files changed

+161
-36
lines changed

src/Serilog.Sinks.MSSqlServer/GlobalSuppressions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Too hard to change. Accepted for now.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerSinkTraits.TryChangeType(System.Object,System.Type,System.Object@)~System.Boolean")]
1111
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Too hard to change. Accepted for now.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerSink.EmitBatchAsync(System.Collections.Generic.IEnumerable{Serilog.Events.LogEvent})~System.Threading.Tasks.Task")]
1212
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Too hard to change. Accepted for now.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerSinkTraits.ConvertPropertiesToXmlStructure(System.Collections.Generic.IEnumerable{System.Collections.Generic.KeyValuePair{System.String,Serilog.Events.LogEventPropertyValue}})~System.String")]
13-
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Too hard to change. Accepted for now.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerSinkTraits.#ctor(System.String,System.String,System.String,Serilog.Sinks.MSSqlServer.ColumnOptions,System.IFormatProvider,System.Boolean,Serilog.Formatting.ITextFormatter,Serilog.Sinks.MSSqlServer.Platform.ISqlTableCreator)")]
13+
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Too hard to change. Accepted for now.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerSinkTraits.#ctor(System.String,System.String,Serilog.Sinks.MSSqlServer.ColumnOptions,System.IFormatProvider,System.Boolean,Serilog.Formatting.ITextFormatter,Serilog.Sinks.MSSqlServer.Platform.ISqlTableCreator)")]
1414
[assembly: SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Serilog core guarantees to call Emit() with non-null logEvent parameter.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerAuditSink.Emit(Serilog.Events.LogEvent)")]
1515
[assembly: SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Serilog core guarantees to call EmitBatchAsync() with non-null logEvent parameter.", Scope = "member", Target = "~M:Serilog.Sinks.MSSqlServer.MSSqlServerSink.EmitBatchAsync(System.Collections.Generic.IEnumerable{Serilog.Events.LogEvent})~System.Threading.Tasks.Task")]
1616
[assembly: SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "Cannot be changed on public classes for backward compatibility reasons.", Scope = "namespaceanddescendants", Target = "Serilog.Sinks.MSSqlServer")]

src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/MSSqlServerAuditSink.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Serilog.Debugging;
2121
using Serilog.Events;
2222
using Serilog.Formatting;
23+
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform;
2324

2425
namespace Serilog.Sinks.MSSqlServer
2526
{
@@ -29,6 +30,7 @@ namespace Serilog.Sinks.MSSqlServer
2930
/// </summary>
3031
public class MSSqlServerAuditSink : ILogEventSink, IDisposable
3132
{
33+
private readonly ISqlConnectionFactory _sqlConnectionFactory;
3234
private readonly MSSqlServerSinkTraits _traits;
3335

3436
/// <summary>
@@ -58,8 +60,8 @@ public MSSqlServerAuditSink(
5860
throw new NotSupportedException($"The {nameof(ColumnOptions.DisableTriggers)} option is not supported for auditing.");
5961
}
6062

61-
_traits = new MSSqlServerSinkTraits(connectionString, tableName, schemaName, columnOptions, formatProvider, autoCreateSqlTable, logEventFormatter);
62-
63+
_sqlConnectionFactory = new SqlConnectionFactory(connectionString);
64+
_traits = new MSSqlServerSinkTraits(_sqlConnectionFactory, tableName, schemaName, columnOptions, formatProvider, autoCreateSqlTable, logEventFormatter);
6365
}
6466

6567
/// <summary>Emit the provided log event to the sink.</summary>
@@ -68,7 +70,7 @@ public void Emit(LogEvent logEvent)
6870
{
6971
try
7072
{
71-
using (var connection = new SqlConnection(_traits.ConnectionString))
73+
using (var connection = _sqlConnectionFactory.Create())
7274
{
7375
connection.Open();
7476
using (SqlCommand command = connection.CreateCommand())

src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/MSSqlServerSink.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using Serilog.Debugging;
2323
using Serilog.Events;
2424
using Serilog.Formatting;
25+
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform;
2526
using Serilog.Sinks.PeriodicBatching;
2627

2728
namespace Serilog.Sinks.MSSqlServer
@@ -31,6 +32,7 @@ namespace Serilog.Sinks.MSSqlServer
3132
/// </summary>
3233
public class MSSqlServerSink : PeriodicBatchingSink
3334
{
35+
private readonly ISqlConnectionFactory _sqlConnectionFactory;
3436
private readonly MSSqlServerSinkTraits _traits;
3537

3638
/// <summary>
@@ -69,7 +71,9 @@ public MSSqlServerSink(
6971
: base(batchPostingLimit, period)
7072
{
7173
columnOptions?.FinalizeConfigurationForSinkConstructor();
72-
_traits = new MSSqlServerSinkTraits(connectionString, tableName, schemaName, columnOptions, formatProvider, autoCreateSqlTable, logEventFormatter);
74+
75+
_sqlConnectionFactory = new SqlConnectionFactory(connectionString);
76+
_traits = new MSSqlServerSinkTraits(_sqlConnectionFactory, tableName, schemaName, columnOptions, formatProvider, autoCreateSqlTable, logEventFormatter);
7377
}
7478

7579
/// <summary>
@@ -88,7 +92,7 @@ protected override async Task EmitBatchAsync(IEnumerable<LogEvent> events)
8892

8993
try
9094
{
91-
using (var cn = new SqlConnection(_traits.ConnectionString))
95+
using (var cn = _sqlConnectionFactory.Create())
9296
{
9397
await cn.OpenAsync().ConfigureAwait(false);
9498
using (var copy = _traits.ColumnOptions.DisableTriggers

src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/MSSqlServerSinkTraits.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
using Serilog.Formatting;
2424
using Serilog.Sinks.MSSqlServer.Output;
2525
using Serilog.Sinks.MSSqlServer.Platform;
26+
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform;
2627

2728
namespace Serilog.Sinks.MSSqlServer
2829
{
@@ -31,7 +32,6 @@ internal class MSSqlServerSinkTraits : IDisposable
3132
{
3233
private bool _disposedValue;
3334

34-
public string ConnectionString { get; }
3535
public string TableName { get; }
3636
public string SchemaName { get; }
3737
public ColumnOptions ColumnOptions { get; }
@@ -42,21 +42,20 @@ internal class MSSqlServerSinkTraits : IDisposable
4242
public ISet<string> StandardColumnNames { get; }
4343

4444
public MSSqlServerSinkTraits(
45-
string connectionString,
45+
ISqlConnectionFactory sqlConnectionFactory,
4646
string tableName,
4747
string schemaName,
4848
ColumnOptions columnOptions,
4949
IFormatProvider formatProvider,
5050
bool autoCreateSqlTable,
5151
ITextFormatter logEventFormatter)
52-
: this(connectionString, tableName, schemaName, columnOptions, formatProvider, autoCreateSqlTable,
53-
logEventFormatter, new SqlTableCreator(new SqlCreateTableWriter()))
52+
: this(tableName, schemaName, columnOptions, formatProvider, autoCreateSqlTable,
53+
logEventFormatter, new SqlTableCreator(new SqlCreateTableWriter(), sqlConnectionFactory))
5454
{
5555
}
5656

5757
// Internal constructor with injectable dependencies for better testability
5858
internal MSSqlServerSinkTraits(
59-
string connectionString,
6059
string tableName,
6160
string schemaName,
6261
ColumnOptions columnOptions,
@@ -65,13 +64,12 @@ internal MSSqlServerSinkTraits(
6564
ITextFormatter logEventFormatter,
6665
ISqlTableCreator sqlTableCreator)
6766
{
68-
if (string.IsNullOrWhiteSpace(connectionString))
69-
throw new ArgumentNullException(nameof(connectionString));
70-
7167
if (string.IsNullOrWhiteSpace(tableName))
7268
throw new ArgumentNullException(nameof(tableName));
7369

74-
ConnectionString = connectionString;
70+
if (sqlTableCreator == null)
71+
throw new ArgumentNullException(nameof(sqlTableCreator));
72+
7573
TableName = tableName;
7674
SchemaName = schemaName;
7775
ColumnOptions = columnOptions ?? new ColumnOptions();
@@ -98,7 +96,7 @@ internal MSSqlServerSinkTraits(
9896
{
9997
try
10098
{
101-
sqlTableCreator.CreateTable(ConnectionString, SchemaName, TableName, EventTable, ColumnOptions); // return code ignored, 0 = failure?
99+
sqlTableCreator.CreateTable(SchemaName, TableName, EventTable, ColumnOptions); // return code ignored, 0 = failure?
102100
}
103101
catch (Exception ex)
104102
{
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Data.SqlClient;
2+
3+
namespace Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform
4+
{
5+
internal interface ISqlConnectionFactory
6+
{
7+
SqlConnection Create();
8+
}
9+
}

src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/Platform/ISqlTableCreator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ namespace Serilog.Sinks.MSSqlServer.Platform
44
{
55
internal interface ISqlTableCreator
66
{
7-
int CreateTable(string connectionString, string schemaName, string tableName, DataTable dataTable, ColumnOptions columnOptions);
7+
int CreateTable(string schemaName, string tableName, DataTable dataTable, ColumnOptions columnOptions);
88
}
99
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Data.SqlClient;
3+
4+
namespace Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform
5+
{
6+
internal class SqlConnectionFactory : ISqlConnectionFactory
7+
{
8+
private readonly string _connectionString;
9+
10+
public SqlConnectionFactory(string connectionString)
11+
{
12+
if (string.IsNullOrWhiteSpace(connectionString))
13+
{
14+
throw new ArgumentNullException(nameof(connectionString));
15+
}
16+
17+
_connectionString = connectionString;
18+
}
19+
20+
public SqlConnection Create() => new SqlConnection(_connectionString);
21+
}
22+
}

src/Serilog.Sinks.MSSqlServer/Sinks/MSSqlServer/Platform/SqlTableCreator.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1-
using System.Data;
1+
using System;
2+
using System.Data;
23
using System.Data.SqlClient;
4+
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform;
35

46
namespace Serilog.Sinks.MSSqlServer.Platform
57
{
68
internal class SqlTableCreator : ISqlTableCreator
79
{
810
private readonly ISqlCreateTableWriter _sqlCreateTableWriter;
11+
private readonly ISqlConnectionFactory _sqlConnectionFactory;
912

10-
public SqlTableCreator(ISqlCreateTableWriter sqlCreateTableWriter)
13+
public SqlTableCreator(ISqlCreateTableWriter sqlCreateTableWriter, ISqlConnectionFactory sqlConnectionFactory)
1114
{
12-
_sqlCreateTableWriter = sqlCreateTableWriter;
15+
_sqlCreateTableWriter = sqlCreateTableWriter ?? throw new ArgumentNullException(nameof(sqlCreateTableWriter));
16+
_sqlConnectionFactory = sqlConnectionFactory ?? throw new ArgumentNullException(nameof(sqlConnectionFactory));
1317
}
1418

15-
public int CreateTable(string connectionString, string schemaName, string tableName, DataTable dataTable, ColumnOptions columnOptions)
19+
public int CreateTable(string schemaName, string tableName, DataTable dataTable, ColumnOptions columnOptions)
1620
{
17-
using (var conn = new SqlConnection(connectionString))
21+
using (var conn = _sqlConnectionFactory.Create())
1822
{
19-
string sql = _sqlCreateTableWriter.GetSqlFromDataTable(schemaName, tableName, dataTable, columnOptions);
20-
using (SqlCommand cmd = new SqlCommand(sql, conn))
23+
var sql = _sqlCreateTableWriter.GetSqlFromDataTable(schemaName, tableName, dataTable, columnOptions);
24+
using (var cmd = new SqlCommand(sql, conn))
2125
{
2226
conn.Open();
2327
return cmd.ExecuteNonQuery();

test/Serilog.Sinks.MSSqlServer.Tests/Sinks/MSSqlServer/MSSqlServerSinkTraitsTests.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,24 @@
99
using Serilog.Formatting;
1010
using Serilog.Parsing;
1111
using Serilog.Sinks.MSSqlServer.Platform;
12+
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform;
1213
using Xunit;
1314

1415
namespace Serilog.Sinks.MSSqlServer.Tests.Sinks.MSSqlServer
1516
{
1617
public class MSSqlServerSinkTraitsTests : IDisposable
1718
{
18-
private readonly string _connectionString = "connectionString";
19+
private readonly Mock<ISqlConnectionFactory> _sqlConnectionFactoryMock;
1920
private readonly string _tableName = "tableName";
2021
private readonly string _schemaName = "schemaName";
2122
private MSSqlServerSinkTraits _sut;
2223
private bool _disposedValue;
2324

25+
public MSSqlServerSinkTraitsTests()
26+
{
27+
_sqlConnectionFactoryMock = new Mock<ISqlConnectionFactory>();
28+
}
29+
2430
[Trait("Bugfix", "#187")]
2531
[Fact]
2632
public void GetColumnsAndValuesCreatesTimeStampOfTypeDateTimeAccordingToColumnOptions()
@@ -162,7 +168,7 @@ public void InitializeWithAutoCreateSqlTableCallsSqlTableCreator()
162168
SetupSut(options, autoCreateSqlTable: true, sqlTableCreator: sqlTableCreatorMock.Object);
163169

164170
// Assert
165-
sqlTableCreatorMock.Verify(c => c.CreateTable(_connectionString, _schemaName, _tableName,
171+
sqlTableCreatorMock.Verify(c => c.CreateTable(_schemaName, _tableName,
166172
It.IsAny<DataTable>(), options),
167173
Times.Once);
168174
}
@@ -178,7 +184,7 @@ public void InitializeWithoutAutoCreateSqlTableDoesNotCallsSqlTableCreator()
178184
SetupSut(options, autoCreateSqlTable: false, sqlTableCreator: sqlTableCreatorMock.Object);
179185

180186
// Assert
181-
sqlTableCreatorMock.Verify(c => c.CreateTable(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(),
187+
sqlTableCreatorMock.Verify(c => c.CreateTable(It.IsAny<string>(), It.IsAny<string>(),
182188
It.IsAny<DataTable>(), It.IsAny<Serilog.Sinks.MSSqlServer.ColumnOptions>()),
183189
Times.Never);
184190
}
@@ -197,14 +203,14 @@ private void SetupSut(
197203
{
198204
if (sqlTableCreator == null)
199205
{
200-
_sut = new MSSqlServerSinkTraits(_connectionString, _tableName, _schemaName,
206+
_sut = new MSSqlServerSinkTraits(_sqlConnectionFactoryMock.Object, _tableName, _schemaName,
201207
options, CultureInfo.InvariantCulture, autoCreateSqlTable, logEventFormatter);
202208
}
203209
else
204210
{
205211
// Internal constructor to use ISqlTableCreator mock
206-
_sut = new MSSqlServerSinkTraits(_connectionString, _tableName, _schemaName,
207-
options, CultureInfo.InvariantCulture, autoCreateSqlTable, logEventFormatter, sqlTableCreator);
212+
_sut = new MSSqlServerSinkTraits(_tableName, _schemaName, options, CultureInfo.InvariantCulture,
213+
autoCreateSqlTable, logEventFormatter, sqlTableCreator);
208214
}
209215
}
210216

test/Serilog.Sinks.MSSqlServer.Tests/Sinks/MSSqlServer/Output/JsonLogEventFormatterTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
using System.Collections.Generic;
33
using System.Data;
44
using System.IO;
5+
using Moq;
56
using Serilog.Events;
67
using Serilog.Parsing;
78
using Serilog.Sinks.MSSqlServer.Output;
9+
using Serilog.Sinks.MSSqlServer.Sinks.MSSqlServer.Platform;
810
using Xunit;
911

1012
namespace Serilog.Sinks.MSSqlServer.Tests.Sinks.MSSqlServer.Output
@@ -136,7 +138,7 @@ private void SetupTest()
136138
{
137139
_testColumnOptions = new Serilog.Sinks.MSSqlServer.ColumnOptions();
138140
_testColumnOptions.Store.Add(StandardColumn.LogEvent);
139-
_testTraits = new MSSqlServerSinkTraits("ConnectionString", "TableName", "SchemaName", _testColumnOptions,
141+
_testTraits = new MSSqlServerSinkTraits(new Mock<ISqlConnectionFactory>().Object, "TableName", "SchemaName", _testColumnOptions,
140142
formatProvider: null, autoCreateSqlTable: false, logEventFormatter: null);
141143
_sut = new JsonLogEventFormatter(_testTraits);
142144
}

0 commit comments

Comments
 (0)