diff --git a/samples/ConsoleAppWithDI/.gitignore b/samples/ConsoleAppWithDI/.gitignore index 1ee53850b..a6a014765 100644 --- a/samples/ConsoleAppWithDI/.gitignore +++ b/samples/ConsoleAppWithDI/.gitignore @@ -9,6 +9,7 @@ *.user *.userosscache *.sln.docstates +*.lutconfig # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/samples/ConsoleAppWithDI/solution/tests/.editorconfig b/samples/ConsoleAppWithDI/solution/tests/.editorconfig index c5142fde3..6d86a4800 100644 --- a/samples/ConsoleAppWithDI/solution/tests/.editorconfig +++ b/samples/ConsoleAppWithDI/solution/tests/.editorconfig @@ -1,5 +1,7 @@ [*.cs] # Wrapping preferences +dotnet_diagnostic.IDE0039.severity=none dotnet_diagnostic.SA0001.severity=none dotnet_diagnostic.SA1123.severity=none dotnet_diagnostic.SA1600.severity=none +dotnet_diagnostic.SA1602.severity=none diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/Commands/Command.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/Commands/Command.cs index fd0685568..fe2c5356e 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/Commands/Command.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/Commands/Command.cs @@ -2,17 +2,11 @@ namespace Maris.ConsoleApp.IntegrationTests.ScopeTests.Commands; -internal class Command : SyncCommand +internal class Command(TestObject1 obj1, TestObject2 obj2) : SyncCommand { internal const string CommandName = "scope-test"; - private readonly TestObject1 obj1; - private readonly TestObject2 obj2; - - public Command(TestObject1 obj1, TestObject2 obj2) - { - this.obj1 = obj1; - this.obj2 = obj2; - } + private readonly TestObject1 obj1 = obj1; + private readonly TestObject2 obj2 = obj2; protected override ICommandResult Execute(Parameter parameter) { diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ObjectStateHistory.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ObjectStateHistory.cs index ea3c3d305..6c0ca285c 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ObjectStateHistory.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ObjectStateHistory.cs @@ -2,7 +2,7 @@ internal static class ObjectStateHistory { - private static readonly List HistoryStore = new(); + private static readonly List HistoryStore = []; internal static IReadOnlyCollection Histories => HistoryStore.AsReadOnly(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ScopedTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ScopedTest.cs index 532143026..6cd7fbfcc 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ScopedTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/ScopedTest.cs @@ -1,6 +1,5 @@ using Maris.ConsoleApp.Hosting; using Maris.ConsoleApp.IntegrationTests.ScopeTests.Commands; -using Maris.Logging.Testing.Xunit; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Xunit.Abstractions; @@ -8,13 +7,8 @@ namespace Maris.ConsoleApp.IntegrationTests.ScopeTests; [Collection(nameof(ScopeTests))] -public class ScopedTest +public class ScopedTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public ScopedTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - [Fact] public async Task Scopedで登録したインスタンスはコマンド実行時に1回だけ初期化される() { @@ -127,7 +121,7 @@ private IHost CreateHost() var builder = Host.CreateDefaultBuilder(args); builder.ConfigureServices((context, services) => { - services.AddTestLogging(this.loggerManager); + services.AddTestLogging(this.LoggerManager); services.AddScoped(); // Command 内で利用 services.AddScoped(); // Command, TestObject1 内で利用 services.AddConsoleAppService(args); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/SingletonTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/SingletonTest.cs index 04a71729a..5c5180c33 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/SingletonTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/SingletonTest.cs @@ -1,6 +1,5 @@ using Maris.ConsoleApp.Hosting; using Maris.ConsoleApp.IntegrationTests.ScopeTests.Commands; -using Maris.Logging.Testing.Xunit; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Xunit.Abstractions; @@ -8,13 +7,8 @@ namespace Maris.ConsoleApp.IntegrationTests.ScopeTests; [Collection(nameof(ScopeTests))] -public class SingletonTest +public class SingletonTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public SingletonTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - [Fact] public async Task Singletonで登録したインスタンスはコマンド実行時に1回だけ初期化される() { @@ -127,7 +121,7 @@ private IHost CreateHost() var builder = Host.CreateDefaultBuilder(args); builder.ConfigureServices((context, services) => { - services.AddTestLogging(this.loggerManager); + services.AddTestLogging(this.LoggerManager); services.AddSingleton(); // Command 内で利用 services.AddSingleton(); // Command, TestObject1 内で利用 services.AddConsoleAppService(args); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject1.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject1.cs index 58d3d7498..355d5f1ed 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject1.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject1.cs @@ -1,10 +1,8 @@ namespace Maris.ConsoleApp.IntegrationTests.ScopeTests; -internal class TestObject1 : TestObjectBase +internal class TestObject1(TestObject2 obj2) : TestObjectBase { - private readonly TestObject2 obj2; - - public TestObject1(TestObject2 obj2) => this.obj2 = obj2; + private readonly TestObject2 obj2 = obj2; internal void DoSomething() { diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject2.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject2.cs index 79fdcbabf..32e64efb3 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject2.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TestObject2.cs @@ -2,9 +2,5 @@ internal class TestObject2 : TestObjectBase { - public TestObject2() - { - } - internal void DoSomething() => this.LogHistory(); } diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TransientTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TransientTest.cs index 077352b54..7cc0b4f03 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TransientTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/ScopeTests/TransientTest.cs @@ -1,6 +1,5 @@ using Maris.ConsoleApp.Hosting; using Maris.ConsoleApp.IntegrationTests.ScopeTests.Commands; -using Maris.Logging.Testing.Xunit; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Xunit.Abstractions; @@ -8,13 +7,8 @@ namespace Maris.ConsoleApp.IntegrationTests.ScopeTests; [Collection(nameof(ScopeTests))] -public class TransientTest +public class TransientTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public TransientTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - [Fact] public async Task Transientで登録したインスタンスはインジェクション時に毎回初期化される() { @@ -130,7 +124,7 @@ private IHost CreateHost() var builder = Host.CreateDefaultBuilder(args); builder.ConfigureServices((context, services) => { - services.AddTestLogging(this.loggerManager); + services.AddTestLogging(this.LoggerManager); services.AddTransient(); // Command 内で利用 services.AddTransient(); // Command, TestObject1 内で利用 services.AddConsoleAppService(args); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/TestBase.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/TestBase.cs new file mode 100644 index 000000000..600dc88c1 --- /dev/null +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.IntegrationTests/TestBase.cs @@ -0,0 +1,15 @@ +using Maris.Logging.Testing.Xunit; +using Xunit.Abstractions; + +namespace Maris.ConsoleApp.IntegrationTests; + +public class TestBase +{ + protected TestBase(ITestOutputHelper testOutputHelper) + { + ArgumentNullException.ThrowIfNull(testOutputHelper); + this.LoggerManager = new TestLoggerManager(testOutputHelper); + } + + protected TestLoggerManager LoggerManager { get; } +} diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/AsyncCommandTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/AsyncCommandTest.cs index c36b38f8b..0fd511016 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/AsyncCommandTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/AsyncCommandTest.cs @@ -26,7 +26,7 @@ public void Parameter_ConsoleAppContextに設定したパラメーターを取 } [Fact] - public void ValidateAllParameterを呼び出すとValidateParameterメソッドが指定したパラメーターを伴って呼び出される() + public void ValidateAllParameter_ValidateParameterメソッドがコンテキストに指定したパラメーターを伴って1回呼び出される() { // Arrange var parameter = new CommandParameter(); @@ -44,7 +44,7 @@ public void ValidateAllParameterを呼び出すとValidateParameterメソッド } [Fact] - public void IAsyncCommandのExecuteAsyncを呼び出すとExecuteAsyncメソッドが指定したパラメーターとキャンセルトークンを伴って呼び出される() + public void IAsyncCommandのExecuteAsync_ExecuteAsyncメソッドがコンテキストに指定したパラメーターとキャンセルトークンを伴って1回呼び出される() { // Arrange var parameter = new CommandParameter(); @@ -64,10 +64,10 @@ public void IAsyncCommandのExecuteAsyncを呼び出すとExecuteAsyncメソッ } [Fact] - public void パラメーターの型にインターフェースを使用できる() + public void Initialize_パラメーターの型にインターフェースを使用できる() { // Arrange - var parameter = new ParameterWithInterface(); + IParameter parameter = new ParameterWithInterface(); var commandAttribute = new CommandAttribute("dummy-command", typeof(CommandWithInterface)); var context = new ConsoleAppContext(commandAttribute, parameter); var commandMock = new Mock(); @@ -78,7 +78,7 @@ public void パラメーターの型にインターフェースを使用でき } [Fact] - public void パラメーターの型とコンテキストのパラメーター型が一致しない場合は例外() + public void Initialize_パラメーターの型とコンテキストのパラメーター型が一致しない_InvalidOperationExceptionが発生する() { // Arrange var parameter = new ParameterWithInterface(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandAttributeTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandAttributeTest.cs index ffa2728c9..bfa279345 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandAttributeTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandAttributeTest.cs @@ -5,7 +5,7 @@ namespace Maris.ConsoleApp.UnitTests.Core; public class CommandAttributeTest { [Fact] - public void Constructor_コマンドの型がnullの場合は例外() + public void Constructor_コマンドの型がnull_ArgumentNullExceptionが発生する() { // Arrange string name = "command"; @@ -19,7 +19,7 @@ public void Constructor_コマンドの型がnullの場合は例外() } [Fact] - public void Constructor_コマンドの型がコマンドの定義を満たしていない場合は例外() + public void Constructor_コマンドの型がコマンドの定義を満たしていない_ArgumentExceptionが発生する() { // Arrange string name = "command"; diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandBaseTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandBaseTest.cs index f17f4f587..a015934ef 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandBaseTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandBaseTest.cs @@ -37,7 +37,7 @@ public void CommandName_初期化時に指定したコマンド名を取得で } [Fact] - public void Context_初期値のまま取得すると例外() + public void Context_初期値のまま取得する_InvalidOperationExceptionが発生する() { // Arrange var command = new CommandImpl(); @@ -68,7 +68,7 @@ public void Context_初期化時に指定したコンテキストを取得でき } [Fact] - public void Initialize_nullで初期化すると例外() + public void Initialize_nullで初期化する_ArgumentNullExceptionが発生する() { // Arrange var command = new CommandImpl(); @@ -82,13 +82,14 @@ public void Initialize_nullで初期化すると例外() } [Fact] - public void ValidateAllParameter_入力パラメータのクラスにプロパティが定義されていない() + public void ValidateAllParameter_入力パラメータのクラスにプロパティが定義されていない_例外が発生しない() { // Arrange var command = new CommandImpl(); string commandName = "dummy-command"; var commandAttribute = new CommandAttribute(commandName, typeof(CommandImpl)); - var context = new ConsoleAppContext(commandAttribute, new object()); + var parameter = new object(); + var context = new ConsoleAppContext(commandAttribute, parameter); command.Initialize(context); // Act and Assert(例外が発生しないこと) @@ -96,13 +97,14 @@ public void ValidateAllParameter_入力パラメータのクラスにプロパ } [Fact] - public void ValidateAllParameter_入力パラメータのクラスにプロパティがあるが検証属性が定義されていない() + public void ValidateAllParameter_入力パラメータのクラスにプロパティがあるが検証属性が定義されていない_例外が発生しない() { // Arrange var command = new CommandImpl(); string commandName = "dummy-command"; var commandAttribute = new CommandAttribute(commandName, typeof(CommandImpl)); - var context = new ConsoleAppContext(commandAttribute, new NoDataAnnotationParameter()); + var parameter = new NoDataAnnotationParameter(); + var context = new ConsoleAppContext(commandAttribute, parameter); command.Initialize(context); // Act and Assert(例外が発生しないこと) @@ -112,7 +114,7 @@ public void ValidateAllParameter_入力パラメータのクラスにプロパ [Theory] [InlineData("", 0)] [InlineData("1234567890", 5)] - public void ValidateAllParameter_入力パラメータのクラスに検証属性を定義したプロパティがあり検証に成功する値が設定されている(string param1, int param2) + public void ValidateAllParameter_入力パラメータのクラスに検証属性を定義したプロパティがあり検証に成功する値が設定されている_例外が発生しない(string param1, int param2) { // Arrange var command = new CommandImpl(); @@ -131,7 +133,7 @@ public void ValidateAllParameter_入力パラメータのクラスに検証属 } [Fact] - public void ValidateAllParameter_入力パラメータのクラスに検証属性を定義したプロパティがあり一部検証に失敗する値が設定されている() + public void ValidateAllParameter_入力パラメータのクラスに検証属性を定義したプロパティがあり一部検証に失敗する値が設定されている_検証失敗メッセージを伴うInvalidParameterExceptionが発生する() { // Arrange var command = new CommandImpl(); @@ -153,13 +155,11 @@ public void ValidateAllParameter_入力パラメータのクラスに検証属 // Assert var ex = Assert.Throws(action); - Assert.Collection( - ex.ValidationResults, - result => Assert.Equal("Param2 は 0 から 5 の間で設定してください。", result.ErrorMessage)); + Assert.Single(ex.ValidationResults, result => result.ErrorMessage == "Param2 は 0 から 5 の間で設定してください。"); } [Fact] - public void ValidateAllParameter_入力パラメータのクラスに検証属性を定義したプロパティがあり複数検証に失敗する値が設定されている() + public void ValidateAllParameter_入力パラメータのクラスに検証属性を定義したプロパティがあり複数検証に失敗する値が設定されている_検証失敗メッセージを伴うInvalidParameterExceptionが発生する() { // Arrange var command = new CommandImpl(); @@ -188,7 +188,7 @@ public void ValidateAllParameter_入力パラメータのクラスに検証属 } [Fact] - public void ValidateAllParameter_コマンドクラスのロジック内でパラメーターの入力値検証エラーがあった() + public void ValidateAllParameter_コマンドクラスのロジック内でパラメーターの入力値検証エラーがあった_InvalidParameterExceptionが発生する() { // Arrange var command = new ValidationErrorCommand(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandExecutorTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandExecutorTest.cs index 49ff9fbce..db71039c1 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandExecutorTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandExecutorTest.cs @@ -8,7 +8,7 @@ namespace Maris.ConsoleApp.UnitTests.Core; public class CommandExecutorTest { [Fact] - public void Constructor_managerがnullの場合は例外() + public void Constructor_managerがnull_ArgumentNullExceptionが発生する() { // Arrange ICommandManager? manager = null; @@ -22,7 +22,7 @@ public void Constructor_managerがnullの場合は例外() } [Fact] - public void Constructor_ロガーがnullの場合は例外() + public void Constructor_ロガーがnullの場合_ArgumentNullExceptionが発生する() { // Arrange var managerMock = new Mock(); @@ -36,7 +36,7 @@ public void Constructor_ロガーがnullの場合は例外() } [Fact] - public void Constructor_managerを使ってコマンドが生成される() + public void Constructor_ICommandManagerのCreateCommandが1回呼び出される() { // Arrange var managerMock = new Mock(); @@ -53,7 +53,7 @@ public void Constructor_managerを使ってコマンドが生成される() } [Fact] - public void Constructor_マネージャーがコマンドを作成できなかった場合は例外() + public void Constructor_ICommandManagerがコマンドを作成できない_ArgumentExceptionが発生する() { // Arrange var managerMock = new Mock(); @@ -74,7 +74,7 @@ public void Constructor_マネージャーがコマンドを作成できなか [InlineData(null)] [InlineData("")] [InlineData("dummy-command")] - public void CommandName_マネージャーで生成したコマンドオブジェクトの名前を取得できる(string? commandName) + public void CommandName_ICommandManagerで生成したコマンドオブジェクトの名前を取得できる(string? commandName) { // Arrange var managerMock = new Mock(); @@ -93,7 +93,7 @@ public void CommandName_マネージャーで生成したコマンドオブジ } [Fact] - public async Task ExecuteCommandAsync_パラメーターの入力検証に失敗した場合は例外() + public async Task ExecuteCommandAsync_パラメーターの入力検証に失敗した_InvalidParameterExceptionが発生する() { // Arrange var commandAttribute = new CommandAttribute("sync-command", typeof(SyncCommandImpl)); @@ -114,13 +114,11 @@ public async Task ExecuteCommandAsync_パラメーターの入力検証に失敗 // Assert var exception = await Assert.ThrowsAsync(action); - Assert.Collection( - exception.ValidationResults, - result => Assert.Equal("StringParam は 5 文字以下に設定してください。", result.ErrorMessage)); + Assert.Single(exception.ValidationResults, result => result.ErrorMessage == "StringParam は 5 文字以下に設定してください。"); } [Fact] - public async Task ExecuteCommandAsync_パラメーターのカスタム入力検証に失敗した場合は例外() + public async Task ExecuteCommandAsync_パラメーターのカスタム入力検証に失敗した_InvalidParameterExceptionが発生する() { // Arrange var parameter = new ValidatableParameter(); @@ -140,13 +138,11 @@ public async Task ExecuteCommandAsync_パラメーターのカスタム入力検 // Assert var exception = await Assert.ThrowsAsync(action); - Assert.Collection( - exception.ValidationResults, - result => Assert.Equal("Validate メソッド内で検証", result.ErrorMessage)); + Assert.Single(exception.ValidationResults, result => result.ErrorMessage == "Validate メソッド内で検証"); } [Fact] - public async Task ExecuteCommandAsync_コマンド内のカスタム入力値検証に失敗した場合は例外() + public async Task ExecuteCommandAsync_コマンド内のカスタム入力値検証に失敗した_InvalidParameterExceptionが発生する() { // Arrange var commandAttribute = new CommandAttribute("sync-command", typeof(SyncCommandImpl)); @@ -182,7 +178,7 @@ public async Task ExecuteCommandAsync_コマンド内のカスタム入力値検 } [Fact] - public async Task ExecuteCommandAsync_SyncCommandの派生コマンドを実行可能() + public async Task ExecuteCommandAsync_SyncCommandの派生コマンドを実行可能_コマンドの戻り値を取得できる() { // Arrange var commandAttribute = new CommandAttribute("sync-command", typeof(SyncCommandImpl)); @@ -236,7 +232,7 @@ public async Task ExecuteCommandAsync_SyncCommandの派生コマンドにパラ } [Fact] - public async Task ExecuteCommandAsync_AsyncCommandの派生コマンドを実行可能() + public async Task ExecuteCommandAsync_AsyncCommandの派生コマンドを実行可能_コマンドの戻り値を取得できる() { // Arrange var commandAttribute = new CommandAttribute("async-command", typeof(AsyncCommandImpl)); @@ -260,7 +256,7 @@ public async Task ExecuteCommandAsync_AsyncCommandの派生コマンドを実行 } [Fact] - public async Task ExecuteCommandAsync_AsyncCommandの派生コマンドにパラメーターとキャンセルトークンが引き渡される() + public async Task ExecuteCommandAsync_AsyncCommandの派生コマンドのExecuteAsyncがパラメーターとキャンセルトークンを伴い1回呼び出される() { // Arrange var commandAttribute = new CommandAttribute("async-command", typeof(AsyncCommand)); @@ -338,7 +334,7 @@ private class ValidatableParameter : IValidatableObject { public IEnumerable Validate(ValidationContext validationContext) { - yield return new ValidationResult("Validate メソッド内で検証", new string[] { "dummy-member-name" }); + yield return new ValidationResult("Validate メソッド内で検証", ["dummy-member-name"]); } } diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandTypeExtensionsTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandTypeExtensionsTest.cs index 68eab7bf4..da85d9994 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandTypeExtensionsTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/CommandTypeExtensionsTest.cs @@ -5,7 +5,7 @@ namespace Maris.ConsoleApp.UnitTests.Core; public class CommandTypeExtensionsTest { [Fact] - public void IsCommandType_コマンドとは無関係の型を指定するとfalseを取得する() + public void IsCommandType_コマンドとは無関係の型を指定_false() { // Arrange Type type = typeof(DateTime); @@ -18,7 +18,7 @@ public void IsCommandType_コマンドとは無関係の型を指定するとfal } [Fact] - public void IsCommandType_CommandBaseだけを継承した型を指定するとfalseを取得する() + public void IsCommandType_CommandBaseだけを継承した型を指定_false() { // Arrange Type type = typeof(OnlyCommandBaseImpl); @@ -33,7 +33,7 @@ public void IsCommandType_CommandBaseだけを継承した型を指定するとf [Theory] [InlineData(typeof(SyncCommandImpl))] [InlineData(typeof(AsyncCommandImpl))] - public void IsCommandType_SyncCommandまたはAsyncCommandを継承した型を指定するとtrueを取得する(Type t) + public void IsCommandType_SyncCommandまたはAsyncCommandを継承した型を指定_true(Type t) { // Arrange Type type = t; diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/ConsoleAppContextTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/ConsoleAppContextTest.cs index 7cd89f008..3848e12ea 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/ConsoleAppContextTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/ConsoleAppContextTest.cs @@ -5,7 +5,7 @@ namespace Maris.ConsoleApp.UnitTests.Core; public class ConsoleAppContextTest { [Fact] - public void Constructor_パラメーターがnullの場合は例外() + public void Constructor_パラメーターがnull_ArgumentNullExceptionが発生する() { // Arrange object? parameter = null; @@ -18,7 +18,7 @@ public void Constructor_パラメーターがnullの場合は例外() } [Fact] - public void Constructor_パラメーターにCommandAttributeがついていない場合は例外() + public void Constructor_パラメーターにCommandAttributeがついていない_ArgumentExceptionが発生する() { // Arrange object parameter = new NoCommandAttributeParameter(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/InvalidParameterExceptionTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/InvalidParameterExceptionTest.cs index 803def5f5..23c89dbf3 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/InvalidParameterExceptionTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/InvalidParameterExceptionTest.cs @@ -6,7 +6,7 @@ namespace Maris.ConsoleApp.UnitTests.Core; public class InvalidParameterExceptionTest { [Fact] - public void Message_メッセージの既定値の確認() + public void Message_メッセージの既定値_コマンドのパラメーターに入力エラーがあります() { // Arrange var ex = new InvalidParameterException(); @@ -19,14 +19,14 @@ public void Message_メッセージの既定値の確認() } [Fact] - public void Message_検証結果が1件登録されている場合() + public void Message_検証結果が1件登録されている_メンバー名とエラーメッセージが含まれている() { // Arrange var errorMessage = "error message"; var memberNames = new string[] { "param1", "param2" }; var validationResults = new List { - new ValidationResult(errorMessage, memberNames), + new(errorMessage, memberNames), }; var ex = new InvalidParameterException(validationResults); @@ -38,7 +38,7 @@ public void Message_検証結果が1件登録されている場合() } [Fact] - public void Message_検証結果が2件登録されている場合() + public void Message_検証結果が2件登録されている場合_メンバー名とエラーメッセージが含まれている() { // Arrange var errorMessage1 = "error message1"; @@ -47,8 +47,8 @@ public void Message_検証結果が2件登録されている場合() var memberNames2 = new string[] { "param2", "param3" }; var validationResults = new List { - new ValidationResult(errorMessage1, memberNames1), - new ValidationResult(errorMessage2, memberNames2), + new(errorMessage1, memberNames1), + new(errorMessage2, memberNames2), }; var ex = new InvalidParameterException(validationResults); @@ -60,7 +60,7 @@ public void Message_検証結果が2件登録されている場合() } [Fact] - public void ValidationResults_検証結果のリストを指定しない場合は空のリストを取得できる() + public void ValidationResults_検証結果のリストを指定しない_空のリスト() { // Arrange var ex = new InvalidParameterException(); @@ -73,15 +73,15 @@ public void ValidationResults_検証結果のリストを指定しない場合 } [Fact] - public void ValidationResults_検証結果のリストを指定した場合はそれを取得できる() + public void ValidationResults_検証結果のリストを指定_指定したリストを取得できる() { // Arrange string errorMessage1 = "error message1"; string errorMessage2 = "error message2"; var results = new List { - new ValidationResult(errorMessage1), - new ValidationResult(errorMessage2), + new(errorMessage1), + new(errorMessage2), }; var ex = new InvalidParameterException(validationResults: results); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/SyncCommandTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/SyncCommandTest.cs index ac99f2e25..6509d495b 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/SyncCommandTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Core/SyncCommandTest.cs @@ -26,7 +26,7 @@ public void Parameter_ConsoleAppContextに設定したパラメーターを取 } [Fact] - public void ValidateAllParameterを呼び出すとValidateParameterメソッドが指定したパラメーターを伴って呼び出される() + public void ValidateAllParameter_ValidateParameterメソッドがコンテキストに指定したパラメーターを伴って1回呼び出される() { // Arrange var parameter = new CommandParameter(); @@ -44,7 +44,7 @@ public void ValidateAllParameterを呼び出すとValidateParameterメソッド } [Fact] - public void ISyncCommandのExecuteを呼び出すとExecuteメソッドが指定したパラメーターを伴って呼び出される() + public void ISyncCommandのExecute_Executeメソッドがコンテキストに指定したパラメーターを伴って1回呼び出される() { // Arrange var parameter = new CommandParameter(); @@ -63,7 +63,7 @@ public void ISyncCommandのExecuteを呼び出すとExecuteメソッドが指定 } [Fact] - public void パラメーターの型にインターフェースを使用できる() + public void Initialize_パラメーターの型にインターフェースを使用できる() { // Arrange var parameter = new ParameterWithInterface(); @@ -77,7 +77,7 @@ public void パラメーターの型にインターフェースを使用でき } [Fact] - public void パラメーターの型とコンテキストのパラメーター型が一致しない場合は例外() + public void Initialize_パラメーターの型とコンテキストのパラメーター型が一致しない_InvalidOperationExceptionが発生する() { // Arrange var parameter = new ParameterWithInterface(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/CommandParameterTypeCollectionTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/CommandParameterTypeCollectionTest.cs index 370b27e6d..46acdda92 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/CommandParameterTypeCollectionTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/CommandParameterTypeCollectionTest.cs @@ -26,7 +26,7 @@ public void InitializeFromAllAssemblies_現在のアプリケーションドメ } [Fact] - public void GetEnumerator_要素を追加せずに取得すると空の列挙子を取得できる() + public void GetEnumerator_要素を追加せずに取得する_空の列挙子() { // Arrange var collection = new CommandParameterTypeCollection(); @@ -39,11 +39,11 @@ public void GetEnumerator_要素を追加せずに取得すると空の列挙子 } [Fact] - public void クラスの定義されていないアセンブリを読み込んでもパラメーターの型は登録されない() + public void AddCommandParameterTypeFrom_クラスの定義されていないアセンブリを読み込む_パラメーターの型は登録されない() { // Arrange var collection = new CommandParameterTypeCollection(); - var testAssembly = new TestAssembly(Array.Empty()); + var testAssembly = new TestAssembly([]); // Act collection.AddCommandParameterTypeFrom(testAssembly); @@ -53,17 +53,11 @@ public void クラスの定義されていないアセンブリを読み込ん } [Fact] - public void パラメーターではないクラスだけが定義されたアセンブリを読み込んでもパラメーターの型は登録されない() + public void AddCommandParameterTypeFrom_パラメーターではないクラスだけが定義されたアセンブリを読み込む_パラメーターの型は登録されない() { // Arrange var collection = new CommandParameterTypeCollection(); - var testAssembly = new TestAssembly( - new Type[] - { - typeof(int), - typeof(DateTime), - typeof(CommandParameterTypeCollection), - }); + var testAssembly = new TestAssembly([typeof(int), typeof(DateTime), typeof(CommandParameterTypeCollection)]); // Act collection.AddCommandParameterTypeFrom(testAssembly); @@ -73,19 +67,18 @@ public void パラメーターではないクラスだけが定義されたア } [Fact] - public void アセンブリからパラメーターの型だけが登録される() + public void AddCommandParameterTypeFrom_パラメーターを含むクラスが定義されたアセンブリを読み込む_アセンブリからパラメーターの型だけが登録される() { // Arrange var collection = new CommandParameterTypeCollection(); var testAssembly = new TestAssembly( - new Type[] - { + [ typeof(int), typeof(DateTime), typeof(CommandParameterTypeCollection), typeof(CommandParameter1), typeof(CommandParameter2), - }); + ]); // Act collection.AddCommandParameterTypeFrom(testAssembly); @@ -98,17 +91,16 @@ public void アセンブリからパラメーターの型だけが登録され } [Fact] - public void 同じ名前のコマンドがあると登録エラーになる() + public void AddCommandParameterTypeFrom_同じ名前のコマンドがある_ArgumentExceptionが発生する() { // Arrange var collection = new CommandParameterTypeCollection(); var testAssembly = new TestAssembly( - new Type[] - { + [ typeof(CommandParameter1), typeof(CommandParameter2), typeof(CommandParameter1Dash), - }); + ]); // Act var action = () => collection.AddCommandParameterTypeFrom(testAssembly); @@ -119,12 +111,12 @@ public void 同じ名前のコマンドがあると登録エラーになる() } [Fact] - public void 読み込んだアセンブリのリストを取得できる() + public void LoadedAssemblies_読み込んだアセンブリのリストを取得できる() { // Arrange var collection = new CommandParameterTypeCollection(); - var assembly1 = new TestAssembly(Array.Empty()); - var assembly2 = new TestAssembly(Array.Empty()); + var assembly1 = new TestAssembly([]); + var assembly2 = new TestAssembly([]); collection.AddCommandParameterTypeFrom(assembly1); collection.AddCommandParameterTypeFrom(assembly2); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppHostedServiceTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppHostedServiceTest.cs index a0fbe2790..86f5e56e8 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppHostedServiceTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppHostedServiceTest.cs @@ -1,20 +1,14 @@ using Maris.ConsoleApp.Core; using Maris.ConsoleApp.Hosting; -using Maris.Logging.Testing.Xunit; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Xunit.Abstractions; namespace Maris.ConsoleApp.UnitTests.Hosting; -public class ConsoleAppHostedServiceTest +public class ConsoleAppHostedServiceTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public ConsoleAppHostedServiceTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - - public static IEnumerable GetContextsAndCommands() + public static TheoryData GetContextsAndCommands() { // パターン1:正常終了するコマンド var commandAttribute1 = new CommandAttribute("dummy-command", typeof(SyncCommandImpl)); @@ -34,25 +28,26 @@ public static IEnumerable GetContextsAndCommands() var context3 = new ConsoleAppContext(commandAttribute3, parameter3); var command3 = new TestCommand(); - return new List + var data = new TheoryData { - new object[] { context1, command1 }, - new object[] { context2, command2 }, - new object[] { context3, command3 }, + { context1, command1 }, + { context2, command2 }, + { context3, command3 }, }; + return data; } [Fact] - public void Constructor_lifetimeがnullの場合は例外() + public void Constructor_lifetimeがnull_ArgumentNullExceptionが発生する() { // Arrange IHostApplicationLifetime? lifetime = null; var settings = new ConsoleAppSettings(); var managerMock = CreateCommandManagerMock(); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); // Act var action = () => new ConsoleAppHostedService(lifetime!, settings, executor, logger); @@ -62,16 +57,16 @@ public void Constructor_lifetimeがnullの場合は例外() } [Fact] - public void Constructor_settingsがnullの場合は例外() + public void Constructor_settingsがnull_ArgumentNullExceptionが発生する() { // Arrange var lifetime = Mock.Of(); ConsoleAppSettings? settings = null; var managerMock = CreateCommandManagerMock(); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); // Act var action = () => new ConsoleAppHostedService(lifetime, settings!, executor, logger); @@ -81,13 +76,13 @@ public void Constructor_settingsがnullの場合は例外() } [Fact] - public void Constructor_executorがnullの場合は例外() + public void Constructor_executorがnull_ArgumentNullExceptionが発生する() { // Arrange var lifetime = Mock.Of(); var settings = new ConsoleAppSettings(); CommandExecutor? executor = null; - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); // Act var action = () => new ConsoleAppHostedService(lifetime, settings, executor!, logger); @@ -97,14 +92,14 @@ public void Constructor_executorがnullの場合は例外() } [Fact] - public void Constructor_loggerがnullの場合は例外() + public void Constructor_loggerがnull_ArgumentNullExceptionが発生する() { // Arrange var lifetime = Mock.Of(); var settings = new ConsoleAppSettings(); var managerMock = CreateCommandManagerMock(); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); ILogger? logger = null; @@ -116,7 +111,7 @@ public void Constructor_loggerがnullの場合は例外() } [Fact] - public async Task StartAsync_コマンドが正常に完了するとコマンドから返却した終了コードが設定される() + public async Task StartAsync_コマンドが正常に完了する_コマンドから返却した終了コードが設定される() { // Arrange var lifetime = Mock.Of(); @@ -129,9 +124,9 @@ public async Task StartAsync_コマンドが正常に完了するとコマンド command.Initialize(context); var managerMock = CreateCommandManagerMock(command); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new ConsoleAppHostedService(lifetime, settings, executor, logger); int actualExitCode = 0; service.SetExitCode = (exitCode) => actualExitCode = exitCode; @@ -145,7 +140,7 @@ public async Task StartAsync_コマンドが正常に完了するとコマンド } [Fact] - public async Task StartAsync_コマンドの入力値エラーがあると設定の入力値検証エラーの終了コードが設定される() + public async Task StartAsync_コマンドの入力値エラーがある_入力値検証エラーの終了コードが設定される() { // Arrange var lifetime = Mock.Of(); @@ -158,9 +153,9 @@ public async Task StartAsync_コマンドの入力値エラーがあると設定 command.Initialize(context); var managerMock = CreateCommandManagerMock(command); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new ConsoleAppHostedService(lifetime, settings, executor, logger); int actualExitCode = 0; service.SetExitCode = (exitCode) => actualExitCode = exitCode; @@ -174,7 +169,7 @@ public async Task StartAsync_コマンドの入力値エラーがあると設定 } [Fact] - public async Task StartAsync_コマンドの実行時に例外が発生すると設定のエラーの既定の終了コードが設定される() + public async Task StartAsync_コマンドの実行時に例外が発生する_既定のエラー終了コードが設定される() { // Arrange var lifetime = Mock.Of(); @@ -187,9 +182,9 @@ public async Task StartAsync_コマンドの実行時に例外が発生すると command.Initialize(context); var managerMock = CreateCommandManagerMock(command); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new ConsoleAppHostedService(lifetime, settings, executor, logger); int actualExitCode = 0; service.SetExitCode = (exitCode) => actualExitCode = exitCode; @@ -204,7 +199,7 @@ public async Task StartAsync_コマンドの実行時に例外が発生すると [Theory] [MemberData(nameof(GetContextsAndCommands))] - public async Task StartAsync_コマンドが完了するとIHostApplicationLifetimeのStopApplicationが呼び出される(ConsoleAppContext context, CommandBase command) + public async Task StartAsync_コマンドが完了_IHostApplicationLifetimeのStopApplicationが1回呼び出される(ConsoleAppContext context, CommandBase command) { // Arrange var lifetimeMock = new Mock(); @@ -213,9 +208,9 @@ public async Task StartAsync_コマンドが完了するとIHostApplicationLifet command.Initialize(context); var managerMock = CreateCommandManagerMock(command); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new ConsoleAppHostedService(lifetime, settings, executor, logger); int actualExitCode = 0; service.SetExitCode = (exitCode) => actualExitCode = exitCode; @@ -236,9 +231,9 @@ public async Task StopAsync_例外が発生しない() var settings = new ConsoleAppSettings(); var managerMock = CreateCommandManagerMock(); var manager = managerMock.Object; - var commandExecutorLogger = this.loggerManager.CreateLogger(); + var commandExecutorLogger = this.CreateTestLogger(); var executor = new CommandExecutor(manager, commandExecutorLogger); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new ConsoleAppHostedService(lifetime, settings, executor, logger); var cancellationToken = new CancellationToken(false); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppSettingsTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppSettingsTest.cs index ffbd81e22..5e32dd2ac 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppSettingsTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ConsoleAppSettingsTest.cs @@ -5,7 +5,7 @@ namespace Maris.ConsoleApp.UnitTests.Hosting; public class ConsoleAppSettingsTest { [Fact] - public void DefaultErrorExitCode_既定値の確認() + public void DefaultErrorExitCode_intの最大値() { // Arrange var settings = new ConsoleAppSettings(); @@ -18,7 +18,7 @@ public void DefaultErrorExitCode_既定値の確認() } [Fact] - public void DefaultValidationErrorExitCode_既定値の確認() + public void DefaultValidationErrorExitCode_intの最小値() { // Arrange var settings = new ConsoleAppSettings(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/DefaultCommandManagerTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/DefaultCommandManagerTest.cs index 7a62f3a57..2716f5fb2 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/DefaultCommandManagerTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/DefaultCommandManagerTest.cs @@ -6,7 +6,7 @@ namespace Maris.ConsoleApp.UnitTests.Hosting; public class DefaultCommandManagerTest { [Fact] - public void Constructor_ConsoleAppContextがnullの場合は例外() + public void Constructor_ConsoleAppContextがnull_ArgumentNullExceptionが発生する() { // Arrange ConsoleAppContext? context = null; @@ -20,7 +20,7 @@ public void Constructor_ConsoleAppContextがnullの場合は例外() } [Fact] - public void Constructor_IServiceProviderがnullの場合は例外() + public void Constructor_IServiceProviderがnull_ArgumentNullExceptionが発生する() { // Arrange var parameter = new TestParameter(); @@ -35,7 +35,7 @@ public void Constructor_IServiceProviderがnullの場合は例外() } [Fact] - public void マネージャーに設定したコンテキストの情報が初期化処理を通してコマンドにも設定される() + public void CreateCommand_マネージャーに設定したコンテキストの情報がコマンドにも設定される() { // Arrange var provider = Mock.Of(); @@ -51,7 +51,7 @@ public void マネージャーに設定したコンテキストの情報が初 } [Fact] - public void ReleaseCommandを呼び出すとスコープがクローズされる() + public void ReleaseCommand_スコープがクローズされる() { // Arrange var provider = Mock.Of(); @@ -67,7 +67,7 @@ public void ReleaseCommandを呼び出すとスコープがクローズされる } [Fact] - public void ReleaseCommandを複数回呼び出しても例外にならずスコープはクローズされる() + public void ReleaseCommand_複数回呼び出しても例外にならずスコープはクローズされる() { // Arrange var provider = Mock.Of(); @@ -94,13 +94,8 @@ protected internal override ICommandResult Execute(TestParameter parameter) => throw new NotImplementedException(); } - private class DefaultCommandManagerMock : DefaultCommandManager + private class DefaultCommandManagerMock(ConsoleAppContext context, IServiceProvider provider) : DefaultCommandManager(context, provider) { - public DefaultCommandManagerMock(ConsoleAppContext context, IServiceProvider provider) - : base(context, provider) - { - } - internal override CommandBase CreateCommandInScope() => new TestCommand(); } diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ServiceCollectionExtensionsTest.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ServiceCollectionExtensionsTest.cs index b4876696b..8e913d8b3 100644 --- a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ServiceCollectionExtensionsTest.cs +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/Hosting/ServiceCollectionExtensionsTest.cs @@ -10,7 +10,7 @@ namespace Maris.ConsoleApp.UnitTests.Hosting; public class ServiceCollectionExtensionsTest { [Fact] - public void コンソールアプリケーションの初期化処理を呼び出すと必要なサービスが登録される() + public void AddConsoleAppService_必要なサービスが登録される() { // Arrange var services = new ServiceCollection(); @@ -52,7 +52,7 @@ public void コンソールアプリケーションの初期化処理を呼び } [Fact] - public void ConsoleAppSettingsの設定処理を指定しないと既定のオブジェクトで初期化される() + public void AddConsoleAppSettings_ConsoleAppSettingsの設定処理を指定しない_既定のオブジェクトで初期化される() { // Arrange var services = new ServiceCollection(); @@ -69,7 +69,7 @@ public void ConsoleAppSettingsの設定処理を指定しないと既定のオ } [Fact] - public void ConsoleAppSettingsの設定処理を指定すると指定した値で初期化される() + public void AddConsoleAppSettings_ConsoleAppSettingsの設定処理を指定する_指定した値で初期化される() { // Arrange var services = new ServiceCollection(); @@ -91,7 +91,7 @@ public void ConsoleAppSettingsの設定処理を指定すると指定した値 } [Fact] - public void アセンブリ内にコマンドが登録されていない場合は例外() + public void アセンブリ内にコマンドが登録されていない_InvalidOperationExceptionが発生する() { // Arrange var services = new ServiceCollection(); @@ -102,7 +102,7 @@ public void アセンブリ内にコマンドが登録されていない場合 services.AddSingleton(provider => testApplicationProcess); var types = Array.Empty(); var assembly1 = new TestAssembly1(types); - var assembly2 = new TestAssembly2(Array.Empty()); + var assembly2 = new TestAssembly2([]); // Act services.AddConsoleAppContext(args, types => @@ -119,7 +119,7 @@ public void アセンブリ内にコマンドが登録されていない場合 } [Fact] - public void 登録されていないコマンド名を指定した場合は検証エラーのエラーコードを伴ってアプリケーションが終了する() + public void 登録されていないコマンド名を指定_検証エラーのエラーコードを伴ってApplicationExceptionが発生する() { // Arrange var services = new ServiceCollection(); @@ -147,7 +147,7 @@ public void 登録されていないコマンド名を指定した場合は検 [Theory] [InlineData("test-command1", typeof(TestParameter1), typeof(TestCommand1))] [InlineData("test-command2", typeof(TestParameter2), typeof(TestCommand2))] - public void 登録されているコマンド名を指定するとDIコンテナーからConsoleAppContextが生成できる(string commandName, Type parameterType, Type commandType) + public void 登録されているコマンド名を指定_DIコンテナーからConsoleAppContextが生成できる(string commandName, Type parameterType, Type commandType) { // Arrange var services = new ServiceCollection(); diff --git a/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/TestBase.cs b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/TestBase.cs new file mode 100644 index 000000000..b0e94889e --- /dev/null +++ b/samples/ConsoleAppWithDI/solution/tests/Maris.ConsoleApp.UnitTests/TestBase.cs @@ -0,0 +1,22 @@ +using Maris.Logging.Testing.Xunit; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Xunit.Abstractions; + +namespace Maris.ConsoleApp.UnitTests; + +public class TestBase +{ + private readonly TestLoggerManager loggerManager; + + protected TestBase(ITestOutputHelper testOutputHelper) + { + ArgumentNullException.ThrowIfNull(testOutputHelper); + this.loggerManager = new TestLoggerManager(testOutputHelper); + } + + protected FakeLogCollector LogCollector => this.loggerManager.LogCollector; + + protected ILogger CreateTestLogger() + => this.loggerManager.CreateLogger(); +} diff --git a/samples/Dressca/dressca-backend/.gitignore b/samples/Dressca/dressca-backend/.gitignore index 1ee53850b..a6a014765 100644 --- a/samples/Dressca/dressca-backend/.gitignore +++ b/samples/Dressca/dressca-backend/.gitignore @@ -9,6 +9,7 @@ *.user *.userosscache *.sln.docstates +*.lutconfig # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/samples/Dressca/dressca-backend/src/Dressca.ApplicationCore/Catalog/CatalogDomainService.cs b/samples/Dressca/dressca-backend/src/Dressca.ApplicationCore/Catalog/CatalogDomainService.cs index 9f8452719..4dc886d5c 100644 --- a/samples/Dressca/dressca-backend/src/Dressca.ApplicationCore/Catalog/CatalogDomainService.cs +++ b/samples/Dressca/dressca-backend/src/Dressca.ApplicationCore/Catalog/CatalogDomainService.cs @@ -51,7 +51,7 @@ await this.catalogRepository.FindAsync( .ToArray(); if (notExistsCatalogItemIds.Any()) { - this.logger.LogWarning( + this.logger.LogInformation( Messages.CatalogItemIdDoesNotExistInRepository, string.Join(',', notExistsCatalogItemIds)); return (ExistsAll: false, CatalogItems: items); diff --git a/samples/Dressca/dressca-backend/tests/.editorconfig b/samples/Dressca/dressca-backend/tests/.editorconfig index c5142fde3..b8668a97c 100644 --- a/samples/Dressca/dressca-backend/tests/.editorconfig +++ b/samples/Dressca/dressca-backend/tests/.editorconfig @@ -1,5 +1,6 @@ [*.cs] # Wrapping preferences +dotnet_diagnostic.IDE0039.severity=none dotnet_diagnostic.SA0001.severity=none dotnet_diagnostic.SA1123.severity=none dotnet_diagnostic.SA1600.severity=none diff --git a/samples/Dressca/dressca-backend/tests/Dressca.IntegrationTest/DatabaseHealthCheckTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.IntegrationTest/DatabaseHealthCheckTest.cs index 53ba2a1c6..0fcf1c80f 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.IntegrationTest/DatabaseHealthCheckTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.IntegrationTest/DatabaseHealthCheckTest.cs @@ -2,17 +2,13 @@ namespace Dressca.IntegrationTest; -public class DatabaseHealthCheckTest : IClassFixture> +public class DatabaseHealthCheckTest(IntegrationTestWebApplicationFactory factory) + : IClassFixture> { - private readonly IntegrationTestWebApplicationFactory factory; - - public DatabaseHealthCheckTest(IntegrationTestWebApplicationFactory factory) - { - this.factory = factory; - } + private readonly IntegrationTestWebApplicationFactory factory = factory; [Fact] - public async Task DatabaseConnectionTest() + public async Task Get_ApiHealth_DBまで含めたヘルスチェックが正常に動作_Healthyを返す() { // Arrange var client = this.factory.CreateClient(); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Accounting/AccountTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Accounting/AccountTest.cs index a917b1cc7..174317ecd 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Accounting/AccountTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Accounting/AccountTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.ApplicationCore.Accounting; public class AccountTest { [Fact] - public void Constructor_会計アイテムがnullの場合例外() + public void Constructor_会計アイテムがnull_ArgumentNullExceptionが発生する() { // Arrange IEnumerable? accountItems = null; @@ -18,7 +18,7 @@ public void Constructor_会計アイテムがnullの場合例外() } [Fact] - public void GetItemsTotalPrice_会計アイテムがないとき会計アイムの合計金額は0円() + public void GetItemsTotalPrice_会計アイテムがない_合計金額は0円() { // Arrange var account = new Account(Array.Empty()); @@ -31,7 +31,7 @@ public void GetItemsTotalPrice_会計アイテムがないとき会計アイム } [Fact] - public void GetItemsTotalPrice_会計アイテムが1件あるとき会計アイムの合計金額は送料と消費税をのぞく合計金額になる() + public void GetItemsTotalPrice_会計アイテムが1件ある_合計金額は送料と消費税をのぞく合計金額になる() { // Arrange var accountItems = new AccountItem[] { new(5, 300m) }; @@ -45,7 +45,7 @@ public void GetItemsTotalPrice_会計アイテムが1件あるとき会計アイ } [Fact] - public void GetItemsTotalPrice_会計アイテムが2件あるとき会計アイムの合計金額は送料と消費税をのぞく合計金額になる() + public void GetItemsTotalPrice_会計アイテムが2件ある_合計金額は送料と消費税をのぞく合計金額になる() { // Arrange var accountItems = new AccountItem[] @@ -63,7 +63,7 @@ public void GetItemsTotalPrice_会計アイテムが2件あるとき会計アイ } [Fact] - public void GetDeliveryCharge_会計アイテムがないとき送料は0円() + public void GetDeliveryCharge_会計アイテムがない_送料は0円() { // Arrange var account = new Account(Array.Empty()); @@ -76,7 +76,7 @@ public void GetDeliveryCharge_会計アイテムがないとき送料は0円() } [Fact] - public void GetDeliveryCharge_会計アイムの合計金額が5000円未満の場合は送料が500円になる() + public void GetDeliveryCharge_会計アイテムの合計金額が5000円未満_送料が500円() { // Arrange var accountItems = new AccountItem[] { new(1, 4999m) }; @@ -90,7 +90,7 @@ public void GetDeliveryCharge_会計アイムの合計金額が5000円未満の } [Fact] - public void GetDeliveryCharge_会計アイムの合計金額が5000円以上の場合は送料が0円になる() + public void GetDeliveryCharge_会計アイテムの合計金額が5000円以上_送料が0円() { // Arrange var accountItems = new AccountItem[] { new(1, 5000m) }; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetApplicationServiceTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetApplicationServiceTest.cs index 943edbfff..421459403 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetApplicationServiceTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetApplicationServiceTest.cs @@ -1,18 +1,12 @@ using Dressca.ApplicationCore.Assets; -using Maris.Logging.Testing.Xunit; using Xunit.Abstractions; namespace Dressca.UnitTests.ApplicationCore.Assets; -public class AssetApplicationServiceTest +public class AssetApplicationServiceTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public AssetApplicationServiceTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - [Fact] - public void GetAssetStreamInfo_リポジトリに指定したアセットコードの情報が見つからない場合は例外() + public void GetAssetStreamInfo_リポジトリに指定したアセットコードの情報が見つからない_AssetNotFoundExceptionが発生する() { // Arrange var assetCode = "dummy"; @@ -21,7 +15,7 @@ public void GetAssetStreamInfo_リポジトリに指定したアセットコー .Setup(r => r.Find(assetCode)) .Returns((Asset?)null); var store = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new AssetApplicationService(repositoryMock.Object, store, logger); // Act @@ -33,7 +27,7 @@ public void GetAssetStreamInfo_リポジトリに指定したアセットコー } [Fact] - public void GetAssetStreamInfo_ストアに指定したアセットコードのストリームが見つからない場合は例外() + public void GetAssetStreamInfo_ストアに指定したアセットコードのストリームが見つからない場合_AssetNotFoundExceptionが発生する() { // Arrange var assetCode = "dummy"; @@ -46,7 +40,7 @@ public void GetAssetStreamInfo_ストアに指定したアセットコードの storeMock .Setup(s => s.GetStream(asset)) .Returns((Stream?)null); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new AssetApplicationService(repositoryMock.Object, storeMock.Object, logger); // Act @@ -72,7 +66,7 @@ public void GetAssetStreamInfo_リポジトリから取得したアセット情 storeMock .Setup(s => s.GetStream(asset)) .Returns(stream); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new AssetApplicationService(repositoryMock.Object, storeMock.Object, logger); // Act diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTest.cs index d0c728405..14c034267 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTest.cs @@ -8,7 +8,7 @@ public class AssetTest [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_アセットコードがnullまたは空の文字列の場合例外(string? assetCode) + public void Constructor_アセットコードがnullまたは空の文字列_ArgumentExceptionが発生する(string? assetCode) { // Arrange var assetType = AssetTypes.Png; @@ -22,7 +22,7 @@ public void Constructor_アセットコードがnullまたは空の文字列の } [Fact] - public void Constructor_アセットタイプが未知の場合例外() + public void Constructor_アセットタイプが未知_NotSupportedExceptionが発生する() { // Arrange var assetCode = "assetCode"; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTypesTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTypesTest.cs index ea221a622..d2addd4ef 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTypesTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Assets/AssetTypesTest.cs @@ -8,7 +8,7 @@ public class AssetTypesTest [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void IsSupportedAssetType_アセットタイプがnullまたは空の文字列の場合(string? assetType) + public void IsSupportedAssetType_アセットタイプがnullまたは空の文字列_false(string? assetType) { // Arrange: Do Nothing // Act @@ -20,7 +20,7 @@ public void IsSupportedAssetType_アセットタイプがnullまたは空の文 [Theory] [InlineData(AssetTypes.Png)] - public void IsSupportedAssetType_アセットタイプが定義済みの場合(string assetType) + public void IsSupportedAssetType_アセットタイプが定義済み_true(string assetType) { // Arrange: Do Nothing // Act diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketApplicationServiceTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketApplicationServiceTest.cs index c567cef80..01e9b67c3 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketApplicationServiceTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketApplicationServiceTest.cs @@ -1,5 +1,4 @@ using Dressca.ApplicationCore.Baskets; -using Maris.Logging.Testing.Xunit; using Xunit.Abstractions; namespace Dressca.UnitTests.ApplicationCore.Baskets; @@ -7,24 +6,19 @@ namespace Dressca.UnitTests.ApplicationCore.Baskets; /// /// 買い物かごアプリケーションサービスの単体テストです。 /// -public class BasketApplicationServiceTest +public class BasketApplicationServiceTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public BasketApplicationServiceTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - private static CancellationToken AnyToken => It.IsAny(); [Theory] [InlineData(null)] [InlineData("")] [InlineData(" ")] - public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idがnullまたは空白なら例外が発生する(string? nullOrEmptyBuyerId) + public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idがnullまたは空白_ArgumentExceptionが発生する(string? nullOrEmptyBuyerId) { // Arrange var repo = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repo, logger); // Act @@ -36,7 +30,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 } [Fact] - public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idに対応する買い物かご情報が存在しない場合買い物かごの作成処理としてリポジトリのGetWithBasketItemsを1度だけ呼出す() + public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idに対応する買い物かご情報が存在しない_買い物かごの作成処理としてリポジトリのGetWithBasketItemsを1度だけ呼出す() { // Arrange const string dummyBuyerId = "dummyId"; @@ -44,7 +38,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 repoMock .Setup(r => r.GetWithBasketItemsAsync(dummyBuyerId, AnyToken)) .ReturnsAsync((Basket?)null); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -55,7 +49,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 } [Fact] - public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idに対応する買い物かご情報が存在しない場合買い物かごの作成処理としてリポジトリのAddAsyncを1度だけ呼出す() + public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idに対応する買い物かご情報が存在しない_買い物かごの作成処理としてリポジトリのAddAsyncを1度だけ呼出す() { // Arrange const string buyerId = "not-exists-Id"; @@ -63,7 +57,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 repoMock .Setup(r => r.GetWithBasketItemsAsync(buyerId, AnyToken)) .ReturnsAsync((Basket?)null); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -78,7 +72,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 } [Fact] - public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idに対応する買い物かご情報が存在しない場合AddAsyncで生成した買い物かごを取得できる() + public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理で購入者Idに対応する買い物かご情報が存在しない_AddAsyncで生成した買い物かごを取得できる() { // Arrange const string buyerId = "not-exists-Id"; @@ -90,7 +84,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 repoMock .Setup(r => r.AddAsync(It.IsAny(), AnyToken)) .ReturnsAsync(newBasket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -106,7 +100,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 // Arrange var buyerId = Guid.NewGuid().ToString("D"); var repoMock = new Mock(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -117,7 +111,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 } [Fact] - public async Task GetOrCreateBasketForUserAsync_買い物かごが取得できたときはリポジトリのAddAsyncを呼び出さない() + public async Task GetOrCreateBasketForUserAsync_買い物かごが取得できた_リポジトリのAddAsyncを呼び出さない() { // Arrange var buyerId = Guid.NewGuid().ToString("D"); @@ -126,7 +120,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごが取得でき repoMock .Setup(r => r.GetWithBasketItemsAsync(buyerId, AnyToken)) .ReturnsAsync(basket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -148,7 +142,7 @@ public async Task GetOrCreateBasketForUserAsync_買い物かごの取得処理 repoMock .Setup(r => r.GetWithBasketItemsAsync(buyerId, AnyToken)) .ReturnsAsync(basket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -172,7 +166,7 @@ public async Task AddItemToBasketAsync_買い物かごへの商品追加処理 repoMock .Setup(r => r.GetAsync(basketId, AnyToken)) .ReturnsAsync(basket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -192,7 +186,7 @@ public async Task AddItemToBasketAsync_買い物かごへの商品追加処理 repoMock .Setup(r => r.GetAsync(basketId, AnyToken)) .ReturnsAsync(basket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -205,11 +199,11 @@ public async Task AddItemToBasketAsync_買い物かごへの商品追加処理 } [Fact] - public async Task AddItemToBasketAsync_買い物かごへの商品追加処理で買い物かごが見つからない場合は業務例外が発生する() + public async Task AddItemToBasketAsync_買い物かごへの商品追加処理で買い物かごが見つからない_BasketNotFoundExceptionが発生する() { // Arrange var repo = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repo, logger); // Act @@ -220,7 +214,7 @@ public async Task AddItemToBasketAsync_買い物かごへの商品追加処理 } [Fact] - public async Task AddItemToBasketAsync_買い物かごへの商品追加処理後に数量が0となる場合買い物かごアイテムは削除される() + public async Task AddItemToBasketAsync_買い物かごへの商品追加処理後に数量が0となる_買い物かごアイテムは削除される() { // Arrange const long basketId = 1; @@ -231,7 +225,7 @@ public async Task AddItemToBasketAsync_買い物かごへの商品追加処理 repoMock .Setup(r => r.GetAsync(basketId, AnyToken)) .ReturnsAsync(basket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -239,7 +233,7 @@ public async Task AddItemToBasketAsync_買い物かごへの商品追加処理 // Assert repoMock.Verify( - r => r.UpdateAsync(It.Is(b => !b.Items.Any()), AnyToken), + r => r.UpdateAsync(It.Is(b => b.Items.Count == 0), AnyToken), Times.Once); } @@ -252,7 +246,7 @@ public async Task DeleteBasketAsync_買い物かごの削除処理はリポジ repoMock .Setup(r => r.GetWithBasketItemsAsync(basketId, AnyToken)) .ReturnsAsync(new Basket("dummy")); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -272,7 +266,7 @@ public async Task DeleteBasketAsync_買い物かごの削除処理はリポジ repoMock .Setup(r => r.GetWithBasketItemsAsync(basketId, AnyToken)) .ReturnsAsync(new Basket(buyerId)); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); // Act @@ -285,11 +279,11 @@ public async Task DeleteBasketAsync_買い物かごの削除処理はリポジ } [Fact] - public async Task DeleteBasketAsync_買い物かごの削除処理で買い物かごが見つからない場合は業務例外が発生する() + public async Task DeleteBasketAsync_買い物かごの削除処理で買い物かごが見つからない_BasketNotFoundExceptionが発生する() { // Arrange var repo = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repo, logger); // Act @@ -300,11 +294,11 @@ public async Task DeleteBasketAsync_買い物かごの削除処理で買い物 } [Fact] - public async Task SetQuantitiesAsync_数量の設定処理で数量パラメータがnullならArgumentNullExceptionが発生する() + public async Task SetQuantitiesAsync_数量パラメータがnull_ArgumentNullExceptionが発生する() { // Arrange var repo = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repo, logger); // Act @@ -315,11 +309,11 @@ public async Task SetQuantitiesAsync_数量の設定処理で数量パラメー } [Fact] - public async Task SetQuantitiesAsync_数量の設定処理で買い物かごが見つからないなら業務例外が発生する() + public async Task SetQuantitiesAsync_買い物かごが見つからない_BasketNotFoundExceptionが発生する() { // Arrange var repo = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repo, logger); var quantities = new Dictionary { { 1L, 1 }, { 2L, 1 }, { 3L, 1 } }; @@ -332,7 +326,7 @@ public async Task SetQuantitiesAsync_数量の設定処理で買い物かごが } [Fact] - public async Task SetQuantitiesAsync_数量の設定処理はリポジトリのUpdateAsyncを1度だけ呼出す() + public async Task SetQuantitiesAsync_リポジトリのUpdateAsyncを1度だけ呼出す() { // Arrange const long basketId = 1L; @@ -341,7 +335,7 @@ public async Task SetQuantitiesAsync_数量の設定処理はリポジトリのU repoMock .Setup(r => r.GetWithBasketItemsAsync(basketId, AnyToken)) .ReturnsAsync(new Basket(buyerId)); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); var quantities = new Dictionary { { 1L, 5 } }; @@ -356,7 +350,7 @@ public async Task SetQuantitiesAsync_数量の設定処理はリポジトリのU } [Fact] - public async Task SetQuantitiesAsync_買い物かごに存在しない商品を指定しても買い物かごには追加されない() + public async Task SetQuantitiesAsync_買い物かごに存在しない商品を指定_買い物かごには追加されない() { // Arrange const long basketId = 1L; @@ -365,7 +359,7 @@ public async Task SetQuantitiesAsync_買い物かごに存在しない商品を repoMock .Setup(r => r.GetWithBasketItemsAsync(basketId, AnyToken)) .ReturnsAsync(new Basket(buyerId)); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); var quantities = new Dictionary { { 1L, 5 } }; @@ -380,7 +374,7 @@ public async Task SetQuantitiesAsync_買い物かごに存在しない商品を } [Fact] - public async Task SetQuantitiesAsync_買い物かごに存在する商品を指定すると買い物かごの商品数が更新される() + public async Task SetQuantitiesAsync_買い物かごに存在する商品を指定_買い物かごの商品数が更新される() { // Arrange const long basketId = 1L; @@ -392,7 +386,7 @@ public async Task SetQuantitiesAsync_買い物かごに存在する商品を指 repoMock .Setup(r => r.GetWithBasketItemsAsync(basketId, AnyToken)) .ReturnsAsync(basket); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new BasketApplicationService(repoMock.Object, logger); var quantities = new Dictionary { { 100L, newQuantity } }; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketItemTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketItemTest.cs index c4bfd9c6d..0b31b49d6 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketItemTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketItemTest.cs @@ -21,7 +21,7 @@ public void GetSubTotal_買い物かごアイテムの小計額は単価と数 } [Fact] - public void Basket_買い物かごのナビゲーションプロパティが初期化されていない場合例外() + public void Basket_買い物かごのナビゲーションプロパティが初期化されていない_InvalidOperationExceptionが発生する() { // Arrange long catalogItemId = 1L; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketTest.cs index a43c3d853..b6911f252 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Baskets/BasketTest.cs @@ -66,12 +66,7 @@ public void AddItem_買い物かご内の商品の数量を加算しても買い basket.AddItem(1L, 1000, 9); // Assert - Assert.Collection( - basket.Items, - item => - { - Assert.Equal(1L, item.CatalogItemId); - }); + Assert.Single(basket.Items, item => item.CatalogItemId == 1L); } [Fact] @@ -85,13 +80,8 @@ public void AddItem_買い物かご内の商品の数量を加算できる() basket.AddItem(1L, 1000, 9); // Assert - Assert.Collection( - basket.Items, - item => - { - Assert.Equal(1L, item.CatalogItemId); - Assert.Equal(10, item.Quantity); - }); + var item = Assert.Single(basket.Items, item => item.CatalogItemId == 1L); + Assert.Equal(10, item.Quantity); } [Theory] @@ -123,16 +113,11 @@ public void AddItem_買い物かご内の商品の数量を減算できる(int f basket.AddItem(1L, 1000, additionalQuantity); // Assert - Assert.Collection( - basket.Items, - item => - { - Assert.Equal(firstQuantity + additionalQuantity, item.Quantity); - }); + Assert.Single(basket.Items, item => item.Quantity == firstQuantity + additionalQuantity); } [Fact] - public void RemoveEmptyItems_買い物かごにアイテムが1件も存在しないとき数量0のアイテムを除去する() + public void RemoveEmptyItems_買い物かごにアイテムが1件も存在しない_アイテムは0件のまま() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -145,7 +130,7 @@ public void RemoveEmptyItems_買い物かごにアイテムが1件も存在し } [Fact] - public void RemoveEmptyItems_買い物かごに数量1のアイテムが1件存在するとき数量0のアイテムを除去する() + public void RemoveEmptyItems_買い物かごに数量1のアイテムが1件存在する_アイテムは変化しない() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -155,17 +140,12 @@ public void RemoveEmptyItems_買い物かごに数量1のアイテムが1件存 basket.RemoveEmptyItems(); // Assert - Assert.Collection( - basket.Items, - item => - { - Assert.Equal(1L, item.CatalogItemId); - Assert.Equal(1, item.Quantity); - }); + var item = Assert.Single(basket.Items, item => item.CatalogItemId == 1L); + Assert.Equal(1, item.Quantity); } [Fact] - public void RemoveEmptyItems_買い物かごに数量0のアイテムが1件存在するとき数量0のアイテムを除去する() + public void RemoveEmptyItems_買い物かごに数量0のアイテムが1件存在する_数量0のアイテムを除去する() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -179,7 +159,7 @@ public void RemoveEmptyItems_買い物かごに数量0のアイテムが1件存 } [Fact] - public void RemoveEmptyItems_買い物かごに数量0のアイテムが2件存在するとき数量0のアイテムを除去する() + public void RemoveEmptyItems_買い物かごに数量0のアイテムが2件存在する_数量0のアイテムを除去する() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -194,7 +174,7 @@ public void RemoveEmptyItems_買い物かごに数量0のアイテムが2件存 } [Fact] - public void RemoveEmptyItems_買い物かごに数量0のアイテムが1件_数量1のアイテムが1件存在するとき_数量0のアイテムを除去する() + public void RemoveEmptyItems_買い物かごに数量0のアイテムが1件_数量1のアイテムが1件存在する_数量0のアイテムを除去する() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -205,17 +185,12 @@ public void RemoveEmptyItems_買い物かごに数量0のアイテムが1件_数 basket.RemoveEmptyItems(); // Assert - Assert.Collection( - basket.Items, - item => - { - Assert.Equal(2L, item.CatalogItemId); - Assert.Equal(1, item.Quantity); - }); + var item = Assert.Single(basket.Items, item => item.CatalogItemId == 2L); + Assert.Equal(1, item.Quantity); } [Fact] - public void RemoveEmptyItems_買い物かごに数量1のアイテムが2件存在するとき数量0のアイテムを除去する() + public void RemoveEmptyItems_買い物かごに数量1のアイテムが2件存在する_アイテムは変化しない() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -254,17 +229,12 @@ public void RemoveEmptyItems_数量0の商品を買い物かごから削除し basket.RemoveEmptyItems(); // Assert - Assert.Collection( - basket.Items, - item => - { - Assert.Equal(2L, item.CatalogItemId); - Assert.Equal(1, item.Quantity); - }); + var item = Assert.Single(basket.Items, item => item.CatalogItemId == 2L); + Assert.Equal(1, item.Quantity); } [Fact] - public void AddItem_数量は0未満にできない() + public void AddItem_数量は0未満にする_ArgumentExceptionが発生する() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -280,7 +250,7 @@ public void AddItem_数量は0未満にできない() [Theory] [InlineData(10, -11)] [InlineData(10, 2147483647)] - public void AddItem_商品の数量を加減算して0未満にはできない(int firstQuantity, int additionalQuantity) + public void AddItem_商品の数量を加減算して0未満にする_ArgumentExceptionが発生する(int firstQuantity, int additionalQuantity) { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -295,7 +265,7 @@ public void AddItem_商品の数量を加減算して0未満にはできない(i } [Fact] - public void Constructor_買い物かごの購入者Idはnullにできない() + public void Constructor_買い物かごの購入者Idをnullにする_ArgumentNullExceptionが発生する() { // Arrange & Act var action = () => new Basket(null!); @@ -305,7 +275,7 @@ public void Constructor_買い物かごの購入者Idはnullにできない() } [Fact] - public void IsInCatalogItem_買い物かご内に存在するカタログアイテムIdを渡す() + public void IsInCatalogItem_買い物かご内に存在するカタログアイテムIdを渡す_true() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -319,7 +289,7 @@ public void IsInCatalogItem_買い物かご内に存在するカタログアイ } [Fact] - public void IsInCatalogItem_買い物かご内に存在しないカタログアイテムIdを渡す() + public void IsInCatalogItem_買い物かご内に存在しないカタログアイテムIdを渡す_false() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -348,7 +318,7 @@ public void GetAccount_買い物かごアイテムの情報をもとにした会 } [Fact] - public void IsEmpty_買い物かごアイテムが空である() + public void IsEmpty_買い物かごアイテムが空_true() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); @@ -361,7 +331,7 @@ public void IsEmpty_買い物かごアイテムが空である() } [Fact] - public void IsEmpty_買い物かごにアイテムが存在する() + public void IsEmpty_買い物かごにアイテムが存在する_false() { // Arrange var basket = new Basket(Guid.NewGuid().ToString()); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogApplicationServiceTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogApplicationServiceTest.cs index 247ddc2b6..fe35f471c 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogApplicationServiceTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogApplicationServiceTest.cs @@ -1,6 +1,5 @@ using System.Linq.Expressions; using Dressca.ApplicationCore.Catalog; -using Maris.Logging.Testing.Xunit; using Xunit.Abstractions; namespace Dressca.UnitTests.ApplicationCore.Catalog; @@ -8,23 +7,18 @@ namespace Dressca.UnitTests.ApplicationCore.Catalog; /// /// カタログアプリケーションサービスの単体テストです。 /// -public class CatalogApplicationServiceTest +public class CatalogApplicationServiceTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public CatalogApplicationServiceTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - private static CancellationToken AnyToken => It.IsAny(); [Fact] - public async Task GetCatalogItemsAsync_カタログ取得処理はリポジトリのFindを1回呼出す() + public async Task GetCatalogItemsAsync_リポジトリのFindAsyncを1回呼出す() { // Arrange var catalogRepositoryMock = new Mock(); var catalogBrandRepository = Mock.Of(); var catalogCategoryRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new CatalogApplicationService(catalogRepositoryMock.Object, catalogBrandRepository, catalogCategoryRepository, logger); const int skip = 1; const int take = 10; @@ -39,13 +33,13 @@ public async Task GetCatalogItemsAsync_カタログ取得処理はリポジト } [Fact] - public async Task GetCatalogItemsAsync_カタログ取得処理はリポジトリのCountを1回呼出す() + public async Task GetCatalogItemsAsync_リポジトリのCountAsyncを1回呼出す() { // Arrange var catalogRepositoryMock = new Mock(); var catalogBrandRepository = Mock.Of(); var catalogCategoryRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new CatalogApplicationService(catalogRepositoryMock.Object, catalogBrandRepository, catalogCategoryRepository, logger); // Act @@ -58,13 +52,13 @@ public async Task GetCatalogItemsAsync_カタログ取得処理はリポジト } [Fact] - public async Task GetBrandsAsync_ブランド取得処理はブランドリポジトリのGetAllを1回呼出す() + public async Task GetBrandsAsync_ブランドリポジトリのGetAllAsyncを1回呼出す() { // Arrange var catalogRepository = Mock.Of(); var catalogBrandRepositoryMock = new Mock(); var catalogCategoryRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new CatalogApplicationService(catalogRepository, catalogBrandRepositoryMock.Object, catalogCategoryRepository, logger); // Act @@ -75,13 +69,13 @@ public async Task GetBrandsAsync_ブランド取得処理はブランドリポ } [Fact] - public async Task GetCategoriesAsync_カテゴリ取得処理はカテゴリリポジトリのGetAllを1回呼出す() + public async Task GetCategoriesAsync_カテゴリリポジトリのGetAllAsyncを1回呼出す() { // Arrange var catalogRepository = Mock.Of(); var catalogBrandRepository = Mock.Of(); var catalogCategoryRepositoryMock = new Mock(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new CatalogApplicationService(catalogRepository, catalogBrandRepository, catalogCategoryRepositoryMock.Object, logger); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogBrandTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogBrandTest.cs index 744d5e26b..842ed72d6 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogBrandTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogBrandTest.cs @@ -21,7 +21,7 @@ public void Constructor_正しくインスタンス化できる() [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_ブランド名は必須(string? brandName) + public void Constructor_ブランド名がnullまたは空白文字_ArgumentExceptionが発生する(string? brandName) { // Arrange & Act var action = () => new CatalogBrand(brandName!); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogCategoryTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogCategoryTest.cs index 6b22b94ff..53b08abc9 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogCategoryTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogCategoryTest.cs @@ -21,7 +21,7 @@ public void Constructor_正しくインスタンス化できる() [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_カテゴリ名は必須(string? categoryName) + public void Constructor_カテゴリ名がnullまたは空白文字_ArgumentExceptionが発生する(string? categoryName) { // Arrange & Act var action = () => new CatalogCategory(categoryName!); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogDomainServiceTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogDomainServiceTest.cs index 2eee4f18a..cf523891b 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogDomainServiceTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogDomainServiceTest.cs @@ -1,21 +1,16 @@ using System.Linq.Expressions; using Dressca.ApplicationCore.Catalog; -using Maris.Logging.Testing.Xunit; +using Microsoft.Extensions.Logging; using Xunit.Abstractions; namespace Dressca.UnitTests.ApplicationCore.Catalog; -public class CatalogDomainServiceTest +public class CatalogDomainServiceTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public CatalogDomainServiceTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - private static CancellationToken AnyToken => It.IsAny(); [Fact] - public async Task ExistsAllAsync_カタログアイテムIdがすべて存在する場合() + public async Task ExistsAllAsync_カタログアイテムIdがすべて存在する_existsAllはfalse_itemsは見つかったカタログアイテムのリスト() { // Arrange var catalogRepositoryMock = new Mock(); @@ -28,11 +23,11 @@ public async Task ExistsAllAsync_カタログアイテムIdがすべて存在す .Setup(r => r.FindAsync(It.IsAny>>(), AnyToken)) .ReturnsAsync(catalogItems); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var domainService = new CatalogDomainService(catalogRepositoryMock.Object, logger); // Act - var (existsAll, items) = await domainService.ExistsAllAsync(new[] { 1L, 2L }); + var (existsAll, items) = await domainService.ExistsAllAsync([1L, 2L]); // Assert Assert.True(existsAll); @@ -43,7 +38,7 @@ public async Task ExistsAllAsync_カタログアイテムIdがすべて存在す } [Fact] - public async Task ExistsAllAsync_カタログアイテムIdが一部だけ存在する場合() + public async Task ExistsAllAsync_カタログアイテムIdが一部だけ存在する_existsAllはfalse_itemsは見つかったカタログアイテムのリスト() { // Arrange var catalogRepositoryMock = new Mock(); @@ -55,21 +50,46 @@ public async Task ExistsAllAsync_カタログアイテムIdが一部だけ存在 .Setup(r => r.FindAsync(It.IsAny>>(), AnyToken)) .ReturnsAsync(catalogItems); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var domainService = new CatalogDomainService(catalogRepositoryMock.Object, logger); // Act - var (existsAll, items) = await domainService.ExistsAllAsync(new[] { 1L, 2L }); + var (existsAll, items) = await domainService.ExistsAllAsync([1L, 2L]); // Assert Assert.False(existsAll); - Assert.Collection( - items, - item => Assert.Equal(2L, item.Id)); + Assert.Single(items, item => item.Id == 2L); + } + + [Fact] + public async Task ExistsAllAsync_カタログアイテムIdが一部だけ存在する_情報ログが1件出る() + { + // Arrange + var catalogRepositoryMock = new Mock(); + var catalogItems = new List + { + CreateCatalogItem(2L), + }; + catalogRepositoryMock + .Setup(r => r.FindAsync(It.IsAny>>(), AnyToken)) + .ReturnsAsync(catalogItems); + + var logger = this.CreateTestLogger(); + var domainService = new CatalogDomainService(catalogRepositoryMock.Object, logger); + + // Act + _ = await domainService.ExistsAllAsync([1L, 2L]); + + // Assert + Assert.Equal(1, this.LogCollector.Count); + var record = this.LogCollector.LatestRecord; + Assert.Equal("指定されたカタログアイテム ID: [1] のカタログアイテムがリポジトリに存在しません。", record.Message); + Assert.Equal(LogLevel.Information, record.Level); + Assert.Equal(new EventId(0), record.Id); } [Fact] - public async Task ExistsAllAsync_カタログアイテムIdが1件も存在しない場合() + public async Task ExistsAllAsync_カタログアイテムIdが1件も存在しない_existsAllはfalse_itemsは空() { // Arrange var catalogRepositoryMock = new Mock(); @@ -78,17 +98,41 @@ public async Task ExistsAllAsync_カタログアイテムIdが1件も存在し .Setup(r => r.FindAsync(It.IsAny>>(), AnyToken)) .ReturnsAsync(catalogItems); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var domainService = new CatalogDomainService(catalogRepositoryMock.Object, logger); // Act - var (existsAll, items) = await domainService.ExistsAllAsync(new[] { 1L }); + var (existsAll, items) = await domainService.ExistsAllAsync([1L]); // Assert Assert.False(existsAll); Assert.Empty(items); } + [Fact] + public async Task ExistsAllAsync_カタログアイテムIdが1件も存在しない_情報ログが1件出る() + { + // Arrange + var catalogRepositoryMock = new Mock(); + var catalogItems = new List(); + catalogRepositoryMock + .Setup(r => r.FindAsync(It.IsAny>>(), AnyToken)) + .ReturnsAsync(catalogItems); + + var logger = this.CreateTestLogger(); + var domainService = new CatalogDomainService(catalogRepositoryMock.Object, logger); + + // Act + _ = await domainService.ExistsAllAsync([1L]); + + // Assert + Assert.Equal(1, this.LogCollector.Count); + var record = this.LogCollector.LatestRecord; + Assert.Equal("指定されたカタログアイテム ID: [1] のカタログアイテムがリポジトリに存在しません。", record.Message); + Assert.Equal(LogLevel.Information, record.Level); + Assert.Equal(new EventId(0), record.Id); + } + private static CatalogItem CreateCatalogItem(long id) { var random = new Random(); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogItemAssetTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogItemAssetTest.cs index 47f663a5e..00915d396 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogItemAssetTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Catalog/CatalogItemAssetTest.cs @@ -8,7 +8,7 @@ public class CatalogItemAssetTest [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_アセットコードがnullまたは空の文字列の場合例外(string? assetCode) + public void Constructor_アセットコードがnullまたは空の文字列_ArgumentExceptionが発生する(string? assetCode) { // Arrange var catalogItemId = 1L; @@ -22,7 +22,7 @@ public void Constructor_アセットコードがnullまたは空の文字列の } [Fact] - public void CatalogItem_カタログアイテムが初期化されていない場合例外() + public void CatalogItem_カタログアイテムが初期化されていない_InvalidOperationExceptionが発生する() { // Arrange string assetCode = "Asset Code"; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/AddressTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/AddressTest.cs index f559c3196..f6e615a1a 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/AddressTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/AddressTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.ApplicationCore.Ordering; public class AddressTest { [Fact] - public void Constructor_郵便番号がnullの場合例外() + public void Constructor_郵便番号がnull_ArgumentNullExceptionが発生する() { // Arrange string? postalCode = null; @@ -21,7 +21,7 @@ public void Constructor_郵便番号がnullの場合例外() } [Fact] - public void Constructor_都道府県がnullの場合例外() + public void Constructor_都道府県がnull_ArgumentNullExceptionが発生する() { // Arrange string postalCode = "100-8924"; @@ -37,7 +37,7 @@ public void Constructor_都道府県がnullの場合例外() } [Fact] - public void Constructor_市区町村がnullの場合例外() + public void Constructor_市区町村がnull_ArgumentNullExceptionが発生する() { // Arrange string postalCode = "100-8924"; @@ -53,7 +53,7 @@ public void Constructor_市区町村がnullの場合例外() } [Fact] - public void Constructor_字がnullの場合例外() + public void Constructor_字がnull_ArgumentNullExceptionが発生する() { // Arrange string postalCode = "100-8924"; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/CatalogItemOrderedTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/CatalogItemOrderedTest.cs index 54af84c9b..53c877f21 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/CatalogItemOrderedTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/CatalogItemOrderedTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.ApplicationCore.Ordering; public class CatalogItemOrderedTest { [Fact] - public void Constructor_カタログアイテムIdが0以下の場合例外() + public void Constructor_カタログアイテムIdが0以下_ArgumentOutOfRangeExceptionが発生する() { // Arrange long catalogItemId = 0L; @@ -25,7 +25,7 @@ public void Constructor_カタログアイテムIdが0以下の場合例外() [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_製品名がnullまたは空の文字列の場合例外(string? productName) + public void Constructor_製品名がnullまたは空の文字列_ArgumentExceptionが発生する(string? productName) { // Arrange long catalogItemId = 1L; @@ -43,7 +43,7 @@ public void Constructor_製品名がnullまたは空の文字列の場合例外( [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_製品コードがnullまたは空の文字列の場合例外(string? productCode) + public void Constructor_製品コードがnullまたは空の文字列_ArgumentExceptionが発生する(string? productCode) { // Arrange long catalogItemId = 1L; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderApplicationServiceTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderApplicationServiceTest.cs index ad4da1277..851e32c02 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderApplicationServiceTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderApplicationServiceTest.cs @@ -2,22 +2,16 @@ using Dressca.ApplicationCore.Baskets; using Dressca.ApplicationCore.Catalog; using Dressca.ApplicationCore.Ordering; -using Maris.Logging.Testing.Xunit; using Xunit.Abstractions; namespace Dressca.UnitTests.ApplicationCore.Ordering; -public class OrderApplicationServiceTest +public class OrderApplicationServiceTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public OrderApplicationServiceTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - private static CancellationToken AnyToken => It.IsAny(); [Fact] - public async Task CreateOrderAsync_注文作成処理は注文リポジトリのAddを1回呼出す() + public async Task CreateOrderAsync_注文リポジトリのAddAsyncを1回呼出す() { // Arrange const long basketId = 1L; @@ -41,7 +35,7 @@ public async Task CreateOrderAsync_注文作成処理は注文リポジトリの orderRepositoryMock .Setup(r => r.AddAsync(It.IsAny(), AnyToken)) .ReturnsAsync(new Order(buyerId, shipTo, CreateDefaultOrderItems())); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new OrderApplicationService(orderRepositoryMock.Object, basketRepositoryMock.Object, catalogRepositoryMock.Object, logger); // Act @@ -54,7 +48,7 @@ public async Task CreateOrderAsync_注文作成処理は注文リポジトリの } [Fact] - public async Task CreateOrderAsync_注文作成処理で指定した買い物かごが存在しない場合は業務例外が発生する() + public async Task CreateOrderAsync_注文作成処理で指定した買い物かごが存在しない_BasketNotFoundExceptionが発生する() { // Arrange const long basketId = 999L; @@ -64,7 +58,7 @@ public async Task CreateOrderAsync_注文作成処理で指定した買い物か .ReturnsAsync((Basket?)null); var catalogRepository = Mock.Of(); var orderRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new OrderApplicationService(orderRepository, basketRepositoryMock.Object, catalogRepository, logger); var shipTo = CreateDefaultShipTo(); @@ -76,7 +70,7 @@ public async Task CreateOrderAsync_注文作成処理で指定した買い物か } [Fact] - public async Task CreateOrderAsync_注文作成処理で指定した買い物かごが空の場合は業務例外が発生する() + public async Task CreateOrderAsync_注文作成処理で指定した買い物かごが空_EmptyBasketOnCheckoutExceptionが発生する() { // Arrange const long basketId = 3L; @@ -88,7 +82,7 @@ public async Task CreateOrderAsync_注文作成処理で指定した買い物か .ReturnsAsync(basket); var catalogRepository = Mock.Of(); var orderRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new OrderApplicationService(orderRepository, basketRepositoryMock.Object, catalogRepository, logger); var shipTo = CreateDefaultShipTo(); @@ -100,7 +94,7 @@ public async Task CreateOrderAsync_注文作成処理で指定した買い物か } [Fact] - public async Task GetOrderAsync_注文リポジトリから取得した情報と指定した購入者IDが合致する場合注文情報を取得できる() + public async Task GetOrderAsync_注文リポジトリから取得した情報と指定した購入者IDが合致する_注文情報を取得できる() { // Arrange var orderId = 10L; @@ -114,7 +108,7 @@ public async Task GetOrderAsync_注文リポジトリから取得した情報と .ReturnsAsync(order); var basketRepository = Mock.Of(); var catalogRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new OrderApplicationService(orderRepositoryMock.Object, basketRepository, catalogRepository, logger); // Act @@ -125,7 +119,7 @@ public async Task GetOrderAsync_注文リポジトリから取得した情報と } [Fact] - public async Task GetOrderAsync_注文リポジトリから取得した情報と指定した購入者IDが異なる場合例外になる() + public async Task GetOrderAsync_注文リポジトリから取得した情報と指定した購入者IDが異なる_OrderNotFoundExceptionが発生する() { // Arrange var orderId = 10L; @@ -139,7 +133,7 @@ public async Task GetOrderAsync_注文リポジトリから取得した情報と .ReturnsAsync(order); var basketRepository = Mock.Of(); var catalogRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new OrderApplicationService(orderRepositoryMock.Object, basketRepository, catalogRepository, logger); // Act @@ -150,7 +144,7 @@ public async Task GetOrderAsync_注文リポジトリから取得した情報と } [Fact] - public async Task GetOrderAsync_注文リポジトリから注文情報を取得できない場合例外になる() + public async Task GetOrderAsync_注文リポジトリから注文情報を取得できない_OrderNotFoundExceptionが発生する() { // Arrange var orderId = 10L; @@ -161,7 +155,7 @@ public async Task GetOrderAsync_注文リポジトリから注文情報を取得 .ReturnsAsync((Order?)null); var basketRepository = Mock.Of(); var catalogRepository = Mock.Of(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); var service = new OrderApplicationService(orderRepositoryMock.Object, basketRepository, catalogRepository, logger); // Act diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemAssetTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemAssetTest.cs index eb2a9a0c4..5992befdb 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemAssetTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemAssetTest.cs @@ -8,7 +8,7 @@ public class OrderItemAssetTest [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_アセットコードがnullまたは空の文字列の場合例外(string? assetCode) + public void Constructor_アセットコードがnullまたは空の文字列_ArgumentExceptionが発生する(string? assetCode) { // Arrange var orderItemId = 1L; @@ -22,7 +22,7 @@ public void Constructor_アセットコードがnullまたは空の文字列の } [Fact] - public void OrderItem_注文アイテムが初期化されていない場合例外() + public void OrderItem_注文アイテムが初期化されていない_InvalidOperationExceptionが発生する() { // Arrange string assetCode = "Asset Code"; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemTest.cs index 1f66289a8..7339f24ca 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderItemTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.ApplicationCore.Ordering; public class OrderItemTest { [Fact] - public void Constructor_注文されたカタログアイテムがnullの場合例外() + public void Constructor_注文されたカタログアイテムがnull_ArgumentNullExceptionが発生する() { // Arrange CatalogItemOrdered? itemOrdered = null; @@ -20,7 +20,7 @@ public void Constructor_注文されたカタログアイテムがnullの場合 } [Fact] - public void Order_注文情報が初期化されていない場合例外() + public void Order_注文情報が初期化されていない_InvalidOperationExceptionが発生する() { // Arrange CatalogItemOrdered itemOrdered = new CatalogItemOrdered(1L, "製品1", "A00000001"); @@ -37,7 +37,7 @@ public void Order_注文情報が初期化されていない場合例外() } [Fact] - public void AddAssets_注文アイテムアセットにnullを追加しようとすると例外() + public void AddAssets_注文アイテムアセットにnullを追加する_ArgumentNullExceptionが発生する() { // Arrange CatalogItemOrdered itemOrdered = new CatalogItemOrdered(1L, "製品1", "A00000001"); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderTest.cs index 19883c0ae..114b7c3a7 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/OrderTest.cs @@ -4,9 +4,9 @@ namespace Dressca.UnitTests.ApplicationCore.Ordering; public class OrderTest { - public static TheoryData> EmptyOrderItems => new() + public static TheoryData?> EmptyOrderItems => new() { - null!, + null, new List(), }; @@ -30,7 +30,7 @@ public void Constructor_正しくインスタンス化できる() [InlineData(null)] [InlineData("")] [InlineData(" ")] - public void Constructor_購入者Idは必須(string? buyerId) + public void Constructor_購入者Idがnullまたは空の文字列_ArgumentExceptionが発生する(string? buyerId) { // Arrange var shipTo = CreateDefaultShipTo(); @@ -44,7 +44,7 @@ public void Constructor_購入者Idは必須(string? buyerId) } [Fact] - public void Constructor_住所は必須() + public void Constructor_住所がnull_ArgumentNullExceptionが発生する() { // Arrange var buyerId = Guid.NewGuid().ToString("D"); @@ -59,7 +59,7 @@ public void Constructor_住所は必須() [Theory] [MemberData(nameof(EmptyOrderItems))] - public void Constructor_注文アイテムは必須(List? emptyOrderItems) + public void Constructor_注文アイテムがnullまたは空のリスト_ArgumentExceptionが発生する(List? emptyOrderItems) { // Arrange var buyerId = Guid.NewGuid().ToString("D"); @@ -165,8 +165,8 @@ private static List CreateDefaultOrderItems() var items = new List() { - new OrderItem(new CatalogItemOrdered(1, productName1, productCode1), 1000m, 1), - new OrderItem(new CatalogItemOrdered(2, productName2, productCode2), 1500m, 2), + new(new CatalogItemOrdered(1, productName1, productCode1), 1000m, 1), + new(new CatalogItemOrdered(2, productName2, productCode2), 1500m, 2), }; return items; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/ShipToTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/ShipToTest.cs index e57f326f6..d1c0905d1 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/ShipToTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/ApplicationCore/Ordering/ShipToTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.ApplicationCore.Ordering; public class ShipToTest { [Fact] - public void Constructor_宛名がnullの場合例外() + public void Constructor_宛名がnull_ArgumentNullExceptionが発生する() { // Arrange string? fullName = null; @@ -19,7 +19,7 @@ public void Constructor_宛名がnullの場合例外() } [Fact] - public void Constructor_住所がnullの場合例外() + public void Constructor_住所がnull_ArgumentNullExceptionが発生する() { // Arrange string fullName = "国会 太郎"; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorCollectionTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorCollectionTest.cs index fbff91d15..8937ab585 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorCollectionTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorCollectionTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.SystemCommon; public class BusinessErrorCollectionTest { [Fact] - public void AddOrMerge_nullを追加しようとすると例外() + public void AddOrMerge_nullを追加する_ArgumentNullExceptionが発生する() { // Arrange var errors = new BusinessErrorCollection(); @@ -31,15 +31,8 @@ public void AddOrMerge_コレクションに追加していないエラーコー errors.AddOrMerge(newBusinessError); // Assert - Assert.Collection( - errors, - error => - { - Assert.Equal(errorCode, error.ErrorCode); - Assert.Collection( - error.ErrorMessages, - message => Assert.Equal(errorMessage, message)); - }); + var error = Assert.Single(errors, error => error.ErrorCode == errorCode); + Assert.Single(error.ErrorMessages, message => message == errorMessage); } [Fact] @@ -58,16 +51,11 @@ public void AddOrMerge_コレクションに追加済みのエラーコードの errors.AddOrMerge(businessError2); // Assert + var error = Assert.Single(errors, error => error.ErrorCode == errorCode); Assert.Collection( - errors, - error => - { - Assert.Equal(errorCode, error.ErrorCode); - Assert.Collection( - error.ErrorMessages, - message => Assert.Equal(errorMessage1, message), - message => Assert.Equal(errorMessage2, message)); - }); + error.ErrorMessages, + message => Assert.Equal(errorMessage1, message), + message => Assert.Equal(errorMessage2, message)); } [Fact] diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorTest.cs index da799d7ab..46cb97eff 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessErrorTest.cs @@ -29,7 +29,7 @@ public void Constructor_引数ありコンストラクターを使用すると { // Arrange string? errorCode = "ERR_CODE"; - string[] errorMessages = new[] { "ERR_MESSAGE1", "ERR_MESSAGE2" }; + string[] errorMessages = ["ERR_MESSAGE1", "ERR_MESSAGE2"]; // Act var error = new BusinessError(errorCode, errorMessages); @@ -43,7 +43,7 @@ public void Constructor_引数ありコンストラクターを使用すると { // Arrange string? errorCode = "ERR_CODE"; - string[] errorMessages = new[] { "ERR_MESSAGE1", "ERR_MESSAGE2" }; + string[] errorMessages = ["ERR_MESSAGE1", "ERR_MESSAGE2"]; // Act var error = new BusinessError(errorCode, errorMessages); @@ -66,16 +66,14 @@ public void AddErrorMessage_nullを追加すると空文字が追加される() error.AddErrorMessage(errorMessage); // Assert - Assert.Collection( - error.ErrorMessages, - errorMessage => Assert.Equal(string.Empty, errorMessage)); + Assert.Single(error.ErrorMessages, errorMessage => errorMessage == string.Empty); } [Fact] public void AddErrorMessage_エラーメッセージを追加できる() { // Arrange - var error = new BusinessError("ERR_CODE", new[] { "ERR_MESSAGE1" }); + var error = new BusinessError("ERR_CODE", ["ERR_MESSAGE1"]); string? errorMessage = "ERR_MESSAGE2"; // Act @@ -89,7 +87,7 @@ public void AddErrorMessage_エラーメッセージを追加できる() } [Fact] - public void ToString_エラーコードが未設定の場合キーが空文字のJSON形式に変換される() + public void ToString_エラーコードが未設定_キーが空文字のJSON形式に変換される() { // Arrange var error = new BusinessError(); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessExceptionTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessExceptionTest.cs index f80e15ea0..62137f163 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessExceptionTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/BusinessExceptionTest.cs @@ -21,7 +21,7 @@ public void ToString_業務エラーのリストが文字列化される() } [Fact] - public void AddOrMergeError_nullを追加しようとすると例外() + public void AddOrMergeError_nullを追加する_ArgumentNullExceptionが発生する() { // Arrange BusinessError? businessError = null; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/ObjectExtensionsTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/ObjectExtensionsTest.cs index fd55b234d..1c27ed0ae 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/ObjectExtensionsTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/SystemCommon/ObjectExtensionsTest.cs @@ -5,7 +5,7 @@ namespace Dressca.UnitTests.SystemCommon; public class ObjectExtensionsTest { [Fact] - public void ThrowIfNull_参照型の値がnullの場合例外() + public void ThrowIfNull_参照型の値がnull_ArgumentNullExceptionが発生する() { // Arrange object? obj = null; @@ -18,7 +18,7 @@ public void ThrowIfNull_参照型の値がnullの場合例外() } [Fact] - public void ThrowIfNull_Nullableな値型の値がnullの場合例外() + public void ThrowIfNull_Nullableな値型の値がnull_ArgumentNullExceptionが発生する() { // Arrange int? intValue = null; diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/TestBase.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/TestBase.cs new file mode 100644 index 000000000..0ee02a152 --- /dev/null +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/TestBase.cs @@ -0,0 +1,28 @@ +using Maris.Logging.Testing.Xunit; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Xunit.Abstractions; + +namespace Dressca.UnitTests; + +public class TestBase +{ + private readonly TestLoggerManager loggerManager; + + protected TestBase(ITestOutputHelper testOutputHelper) + { + ArgumentNullException.ThrowIfNull(testOutputHelper); + this.loggerManager = new TestLoggerManager(testOutputHelper); + } + + protected FakeLogCollector LogCollector => this.loggerManager.LogCollector; + + protected ILogger CreateTestLogger() + => this.loggerManager.CreateLogger(); + + protected ILogger CreateTestLogger(Type type) + => this.loggerManager.CreateLogger(type); + + protected ILogger CreateTestLogger(string categoryName) + => this.loggerManager.CreateLogger(categoryName); +} diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Assets/AssetExtensionsTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Assets/AssetExtensionsTest.cs index 507718bb2..8b993cb32 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Assets/AssetExtensionsTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Assets/AssetExtensionsTest.cs @@ -6,7 +6,7 @@ namespace Dressca.UnitTests.Web.Assets; public class AssetExtensionsTest { [Fact] - public void GetContentType_アセットがnullの場合例外() + public void GetContentType_アセットがnull_ArgumentNullExceptionが発生する() { // Arrange Asset? asset = null; @@ -19,7 +19,7 @@ public void GetContentType_アセットがnullの場合例外() } [Fact] - public void GetContentType_アセットタイプがPNGの場合() + public void GetContentType_アセットタイプがPNG_imagepngを取得できる() { // Arrange Asset asset = new Asset("asset-code", AssetTypes.Png); diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Baskets/HttpContextExtensionsTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Baskets/HttpContextExtensionsTest.cs index 9212a4a71..0b29ecfcd 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Baskets/HttpContextExtensionsTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Baskets/HttpContextExtensionsTest.cs @@ -6,7 +6,7 @@ namespace Dressca.UnitTests.Web.Baskets; public class HttpContextExtensionsTest { [Fact] - public void GetBuyerId_購入者IdがHttpContextに存在しない場合新たにGuid形式の購入者Idが発行される() + public void GetBuyerId_購入者IdがHttpContextに存在しない_新たにGuid形式の購入者Idが発行される() { // Arrange var items = new Dictionary(); @@ -21,7 +21,7 @@ public void GetBuyerId_購入者IdがHttpContextに存在しない場合新た } [Fact] - public void GetBuyerId_購入者Idが文字列型ではない場合新たにGuid形式の購入者Idが発行される() + public void GetBuyerId_購入者Idが文字列型ではない_新たにGuid形式の購入者Idが発行される() { // Arrange var items = new Dictionary @@ -42,7 +42,7 @@ public void GetBuyerId_購入者Idが文字列型ではない場合新たにGuid [InlineData(null)] [InlineData("")] [InlineData("not-guid-value")] - public void GetBuyerId_購入者IdがGuidの文字列ではない場合新たにGuid形式の購入者Idが発行される(string? itemValue) + public void GetBuyerId_購入者IdがGuidの文字列ではない_新たにGuid形式の購入者Idが発行される(string? itemValue) { // Arrange var items = new Dictionary @@ -60,7 +60,7 @@ public void GetBuyerId_購入者IdがGuidの文字列ではない場合新たに } [Fact] - public void GetBuyerId_購入者IdがGuidの文字列の場合設定されている値を取得できる() + public void GetBuyerId_購入者IdがGuidの文字列_設定されている値を取得できる() { // Arrange var buyerId = Guid.NewGuid().ToString(); @@ -91,13 +91,8 @@ public void SetBuyerId_購入者Idを新たに追加できる() HttpContextExtensions.SetBuyerId(httpContextMock.Object, buyerId); // Assert - Assert.Collection( - items, - item => - { - Assert.Equal("Dressca-BuyerId", item.Key); - Assert.Equal(buyerId, item.Value); - }); + var item = Assert.Single(items, item => "Dressca-BuyerId".Equals(item.Key)); + Assert.Equal(buyerId, item.Value); } [Fact] @@ -116,12 +111,7 @@ public void SetBuyerId_購入者Idを上書きできる() HttpContextExtensions.SetBuyerId(httpContextMock.Object, buyerId); // Assert - Assert.Collection( - items, - item => - { - Assert.Equal("Dressca-BuyerId", item.Key); - Assert.Equal(buyerId, item.Value); - }); + var item = Assert.Single(items, item => "Dressca-BuyerId".Equals(item.Key)); + Assert.Equal(buyerId, item.Value); } } diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionDevelopmentFilterTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionDevelopmentFilterTest.cs index 440b1fd37..9ce6ea907 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionDevelopmentFilterTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionDevelopmentFilterTest.cs @@ -1,6 +1,5 @@ using Dressca.SystemCommon; using Dressca.Web.Runtime; -using Maris.Logging.Testing.Xunit; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; @@ -8,17 +7,13 @@ using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Logging; using Xunit.Abstractions; namespace Dressca.UnitTests.Web.Runtime; -public class BusinessExceptionDevelopmentFilterTest +public class BusinessExceptionDevelopmentFilterTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public BusinessExceptionDevelopmentFilterTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - [Fact] public void OnException_業務エラーの情報がActionResultの値に設定される() { @@ -36,16 +31,11 @@ public void OnException_業務エラーの情報がActionResultの値に設定 // Assert var result = Assert.IsType(context.Result); var value = Assert.IsType(result.Value); + var error = Assert.Single(value.Errors, error => errorCode.Equals(error.Key)); Assert.Collection( - value.Errors, - error => - { - Assert.Equal(errorCode, error.Key); - Assert.Collection( - error.Value, - message => Assert.Equal(errorMessage1, message), - message => Assert.Equal(errorMessage2, message)); - }); + error.Value, + message => Assert.Equal(errorMessage1, message), + message => Assert.Equal(errorMessage2, message)); } [Fact] @@ -68,6 +58,29 @@ public void OnException_業務例外のスタックトレースがdetailに設 Assert.Equal(context.Exception.ToString(), value.Detail); } + [Fact] + public void OnException_情報ログが1件登録される() + { + // Arrange + var filter = this.CreateFilter(); + var errorCode = "ERR_CODE"; + var errorMessage1 = "ERR_MESSAGE1"; + var errorMessage2 = "ERR_MESSAGE2"; + var businessError = new BusinessError(errorCode, errorMessage1, errorMessage2); + var context = CreateExceptionContext(businessError); + + // Act + filter.OnException(context); + + // Assert + Assert.Equal(1, this.LogCollector.Count); + var record = this.LogCollector.LatestRecord; + Assert.Equal("業務エラーが発生しました。", record.Message); + Assert.Equal(LogLevel.Information, record.Level); + Assert.Equal(new EventId(0), record.Id); + Assert.Same(context.Exception, record.Exception); + } + private static ExceptionContext CreateExceptionContext(BusinessError businessError) { var httpContext = new DefaultHttpContext(); @@ -84,7 +97,7 @@ private static ExceptionContext CreateExceptionContext(BusinessError businessErr private BusinessExceptionDevelopmentFilter CreateFilter() { var problemDetailsFactory = new TestProblemDetailsFactory(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); return new BusinessExceptionDevelopmentFilter(problemDetailsFactory, logger); } diff --git a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionFilterTest.cs b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionFilterTest.cs index 07a7dd343..7437c09fb 100644 --- a/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionFilterTest.cs +++ b/samples/Dressca/dressca-backend/tests/Dressca.UnitTests/Web/Runtime/BusinessExceptionFilterTest.cs @@ -1,6 +1,5 @@ using Dressca.SystemCommon; using Dressca.Web.Runtime; -using Maris.Logging.Testing.Xunit; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; @@ -8,17 +7,13 @@ using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Logging; using Xunit.Abstractions; namespace Dressca.UnitTests.Web.Runtime; -public class BusinessExceptionFilterTest +public class BusinessExceptionFilterTest(ITestOutputHelper testOutputHelper) : TestBase(testOutputHelper) { - private readonly TestLoggerManager loggerManager; - - public BusinessExceptionFilterTest(ITestOutputHelper testOutputHelper) - => this.loggerManager = new TestLoggerManager(testOutputHelper); - [Fact] public void OnException_業務エラーの情報がActionResultの値に設定される() { @@ -36,16 +31,11 @@ public void OnException_業務エラーの情報がActionResultの値に設定 // Assert var result = Assert.IsType(context.Result); var value = Assert.IsType(result.Value); + var error = Assert.Single(value.Errors, error => errorCode.Equals(error.Key)); Assert.Collection( - value.Errors, - error => - { - Assert.Equal(errorCode, error.Key); - Assert.Collection( - error.Value, - message => Assert.Equal(errorMessage1, message), - message => Assert.Equal(errorMessage2, message)); - }); + error.Value, + message => Assert.Equal(errorMessage1, message), + message => Assert.Equal(errorMessage2, message)); } [Fact] @@ -68,6 +58,29 @@ public void OnException_業務例外のスタックトレースがdetailに設 Assert.Null(value.Detail); } + [Fact] + public void OnException_情報ログが1件登録される() + { + // Arrange + var filter = this.CreateFilter(); + var errorCode = "ERR_CODE"; + var errorMessage1 = "ERR_MESSAGE1"; + var errorMessage2 = "ERR_MESSAGE2"; + var businessError = new BusinessError(errorCode, errorMessage1, errorMessage2); + var context = CreateExceptionContext(businessError); + + // Act + filter.OnException(context); + + // Assert + Assert.Equal(1, this.LogCollector.Count); + var record = this.LogCollector.LatestRecord; + Assert.Equal("業務エラーが発生しました。", record.Message); + Assert.Equal(LogLevel.Information, record.Level); + Assert.Equal(new EventId(0), record.Id); + Assert.Same(context.Exception, record.Exception); + } + private static ExceptionContext CreateExceptionContext(BusinessError businessError) { var httpContext = new DefaultHttpContext(); @@ -84,7 +97,7 @@ private static ExceptionContext CreateExceptionContext(BusinessError businessErr private BusinessExceptionFilter CreateFilter() { var problemDetailsFactory = new TestProblemDetailsFactory(); - var logger = this.loggerManager.CreateLogger(); + var logger = this.CreateTestLogger(); return new BusinessExceptionFilter(problemDetailsFactory, logger); } diff --git a/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerManagerTest.cs b/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerManagerTest.cs index 8de0868cf..ade0217a9 100644 --- a/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerManagerTest.cs +++ b/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerManagerTest.cs @@ -126,7 +126,7 @@ public void LogCollector_CanGetLoggedRecords_Double() secondRecord => { Assert.Equal(LogLevel.Trace, secondRecord.Level); - Assert.Equal(default(EventId), secondRecord.Id); + Assert.Equal(default, secondRecord.Id); Assert.Null(secondRecord.Exception); Assert.Equal(message2, secondRecord.Message); }); diff --git a/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerServiceCollectionExtensionsTest.cs b/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerServiceCollectionExtensionsTest.cs index 294bcdcb5..cf1662cb3 100644 --- a/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerServiceCollectionExtensionsTest.cs +++ b/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/TestLoggerServiceCollectionExtensionsTest.cs @@ -38,7 +38,7 @@ public void AddTestLogging_LoggerManagerIsNull_ThrowsArgumentNullException() } [Fact] - public void AddTestLogging_ValidInputs_AddsTestLoggingAndTwoLoggerProviders() + public void AddTestLogging_ValidInputs_AddsLoggerAndTwoLoggerProviders() { // Arrange var services = new ServiceCollection(); diff --git a/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/XunitLoggerTest.cs b/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/XunitLoggerTest.cs index a73272ee7..e1853c34e 100644 --- a/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/XunitLoggerTest.cs +++ b/samples/Dressca/dressca-backend/tests/Maris.Logging.Testing.Tests/Xunit/XunitLoggerTest.cs @@ -6,8 +6,19 @@ namespace Maris.Logging.Testing.Tests.Xunit; public class XunitLoggerTest { - public static IEnumerable LogLevels - => Enum.GetValues().Select(logLevel => new object[] { logLevel }); + public static TheoryData LogLevels + { + get + { + var data = new TheoryData(); + foreach (var logLevel in Enum.GetValues()) + { + data.Add(logLevel); + } + + return data; + } + } [Fact] public void Constructor_ThrowsException_WhenTestOutputHelperIsNull()