DatabaseCfgTests.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. using Apq.Cfg.Database;
  2. namespace Apq.Cfg.Tests;
  3. /// <summary>
  4. /// 数据库配置源测试
  5. /// 注意:这些测试需要配置数据库连接字符串才能运行
  6. /// </summary>
  7. public class DatabaseCfgTests : IAsyncLifetime
  8. {
  9. private ICfgRoot? _cfg;
  10. private readonly string _tableName;
  11. public DatabaseCfgTests()
  12. {
  13. _tableName = $"ApqCfgTest_{Guid.NewGuid():N}";
  14. }
  15. public Task InitializeAsync()
  16. {
  17. if (!TestSettings.IsDatabaseConfigured)
  18. {
  19. return Task.CompletedTask;
  20. }
  21. _cfg = new CfgBuilder()
  22. .AddDatabase(options =>
  23. {
  24. options.Provider = TestSettings.DatabaseProvider;
  25. options.ConnectionString = TestSettings.DatabaseConnectionString;
  26. options.Table = _tableName;
  27. options.KeyColumn = "ConfigKey";
  28. options.ValueColumn = "ConfigValue";
  29. }, level: 0, isPrimaryWriter: true)
  30. .Build();
  31. return Task.CompletedTask;
  32. }
  33. public async Task DisposeAsync()
  34. {
  35. if (_cfg != null)
  36. {
  37. await _cfg.DisposeAsync();
  38. }
  39. // 清理测试表
  40. if (TestSettings.IsDatabaseConfigured)
  41. {
  42. try
  43. {
  44. // 这里可以添加清理表的逻辑
  45. // 由于不同数据库语法不同,暂时跳过
  46. }
  47. catch
  48. {
  49. // 忽略清理错误
  50. }
  51. }
  52. }
  53. [SkippableFact]
  54. public async Task SetAndGet_SimpleValue_Works()
  55. {
  56. Skip.If(!TestSettings.IsDatabaseConfigured, "数据库连接字符串未配置,跳过测试");
  57. // Arrange & Act
  58. _cfg!.Set("TestKey", "TestValue");
  59. await _cfg.SaveAsync();
  60. // 重新创建配置实例来验证持久化
  61. await using var cfg2 = new CfgBuilder()
  62. .AddDatabase(options =>
  63. {
  64. options.Provider = TestSettings.DatabaseProvider;
  65. options.ConnectionString = TestSettings.DatabaseConnectionString;
  66. options.Table = _tableName;
  67. options.KeyColumn = "ConfigKey";
  68. options.ValueColumn = "ConfigValue";
  69. }, level: 0)
  70. .Build();
  71. // Assert
  72. Assert.Equal("TestValue", cfg2.Get("TestKey"));
  73. }
  74. [SkippableFact]
  75. public async Task SetAndGet_NestedKey_Works()
  76. {
  77. Skip.If(!TestSettings.IsDatabaseConfigured, "数据库连接字符串未配置,跳过测试");
  78. // Arrange & Act
  79. _cfg!.Set("Settings:Value1", "Value1");
  80. _cfg.Set("Settings:Value2", "Value2");
  81. await _cfg.SaveAsync();
  82. // Assert
  83. await using var cfg2 = new CfgBuilder()
  84. .AddDatabase(options =>
  85. {
  86. options.Provider = TestSettings.DatabaseProvider;
  87. options.ConnectionString = TestSettings.DatabaseConnectionString;
  88. options.Table = _tableName;
  89. options.KeyColumn = "ConfigKey";
  90. options.ValueColumn = "ConfigValue";
  91. }, level: 0)
  92. .Build();
  93. Assert.Equal("Value1", cfg2.Get("Settings:Value1"));
  94. Assert.Equal("Value2", cfg2.Get("Settings:Value2"));
  95. }
  96. [SkippableFact]
  97. public async Task Remove_Key_Works()
  98. {
  99. Skip.If(!TestSettings.IsDatabaseConfigured, "数据库连接字符串未配置,跳过测试");
  100. // Arrange
  101. _cfg!.Set("ToRemove", "Value");
  102. await _cfg.SaveAsync();
  103. // Act
  104. _cfg.Remove("ToRemove");
  105. await _cfg.SaveAsync();
  106. // Assert
  107. await using var cfg2 = new CfgBuilder()
  108. .AddDatabase(options =>
  109. {
  110. options.Provider = TestSettings.DatabaseProvider;
  111. options.ConnectionString = TestSettings.DatabaseConnectionString;
  112. options.Table = _tableName;
  113. options.KeyColumn = "ConfigKey";
  114. options.ValueColumn = "ConfigValue";
  115. }, level: 0)
  116. .Build();
  117. Assert.False(cfg2.Exists("ToRemove"));
  118. }
  119. [SkippableFact]
  120. public async Task Exists_Key_ReturnsCorrectResult()
  121. {
  122. Skip.If(!TestSettings.IsDatabaseConfigured, "数据库连接字符串未配置,跳过测试");
  123. // Arrange
  124. _cfg!.Set("ExistsKey", "Value");
  125. await _cfg.SaveAsync();
  126. // Assert
  127. Assert.True(_cfg.Exists("ExistsKey"));
  128. Assert.False(_cfg.Exists("NotExistsKey"));
  129. }
  130. [SkippableFact]
  131. public void Database_OverridesJson_WhenHigherLevel()
  132. {
  133. Skip.If(!TestSettings.IsDatabaseConfigured, "数据库连接字符串未配置,跳过测试");
  134. // Arrange
  135. var tempDir = Path.Combine(Path.GetTempPath(), $"ApqCfgTests_{Guid.NewGuid():N}");
  136. Directory.CreateDirectory(tempDir);
  137. try
  138. {
  139. var jsonPath = Path.Combine(tempDir, "config.json");
  140. File.WriteAllText(jsonPath, """{"Setting": "JsonValue"}""");
  141. // 先设置数据库值
  142. _cfg!.Set("Setting", "DatabaseValue");
  143. _cfg.SaveAsync().Wait();
  144. using var cfg = new CfgBuilder()
  145. .AddJson(jsonPath, level: 0, writeable: false)
  146. .AddDatabase(options =>
  147. {
  148. options.Provider = TestSettings.DatabaseProvider;
  149. options.ConnectionString = TestSettings.DatabaseConnectionString;
  150. options.Table = _tableName;
  151. options.KeyColumn = "ConfigKey";
  152. options.ValueColumn = "ConfigValue";
  153. }, level: 1)
  154. .Build();
  155. // Assert
  156. Assert.Equal("DatabaseValue", cfg.Get("Setting"));
  157. }
  158. finally
  159. {
  160. Directory.Delete(tempDir, true);
  161. }
  162. }
  163. }