mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-23 03:04:29 +08:00
- 为 AsyncLogAppender 添加完整功能测试,包括异步写入、缓冲区管理、并发处理等场景 - 为 CachedLoggerFactory 添加缓存机制测试,验证相同名称和级别的日志记录器重用 - 为 CompositeFilter 添加过滤器组合测试,验证多个过滤器的逻辑组合功能 - 为 CompositeLogger 添加复合日志记录器测试,验证多追加器写入和级别过滤功能 - 为 ConsoleAppender 添加控制台追加器测试,验证格式化输出和过滤器支持 - 为 DefaultLogFormatter 添加默认格式化器测试,验证基本格式化和异常处理功能 - 为 FileAppender 添加文件追加器测试,验证文件写入、目录创建和追加模式功能 - 为 JsonLogFormatter 添加 JSON 格式化器测试,验证 JSON 输出和属性序列化功能 - 为 LogContext 添加日志上下文测试,验证属性推送和作用域管理功能
204 lines
5.3 KiB
C#
204 lines
5.3 KiB
C#
using GFramework.Core.Abstractions.logging;
|
|
using NUnit.Framework;
|
|
|
|
namespace GFramework.Core.Tests.logging;
|
|
|
|
/// <summary>
|
|
/// 测试 LogContext 的功能和行为
|
|
/// </summary>
|
|
[TestFixture]
|
|
public class LogContextTests
|
|
{
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
LogContext.Clear();
|
|
}
|
|
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
LogContext.Clear();
|
|
}
|
|
|
|
[Test]
|
|
public void Current_WhenEmpty_ShouldReturnEmptyDictionary()
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current, Is.Not.Null);
|
|
Assert.That(current.Count, Is.EqualTo(0));
|
|
}
|
|
|
|
[Test]
|
|
public void Push_ShouldAddPropertyToContext()
|
|
{
|
|
using (LogContext.Push("Key1", "Value1"))
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current.Count, Is.EqualTo(1));
|
|
Assert.That(current["Key1"], Is.EqualTo("Value1"));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithMultipleProperties_ShouldAddAllProperties()
|
|
{
|
|
using (LogContext.PushProperties(("Key1", "Value1"), ("Key2", 123)))
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current.Count, Is.EqualTo(2));
|
|
Assert.That(current["Key1"], Is.EqualTo("Value1"));
|
|
Assert.That(current["Key2"], Is.EqualTo(123));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithNestedContext_ShouldMergeProperties()
|
|
{
|
|
using (LogContext.Push("Key1", "Value1"))
|
|
{
|
|
using (LogContext.Push("Key2", "Value2"))
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current.Count, Is.EqualTo(2));
|
|
Assert.That(current["Key1"], Is.EqualTo("Value1"));
|
|
Assert.That(current["Key2"], Is.EqualTo("Value2"));
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithSameKey_ShouldOverrideValue()
|
|
{
|
|
using (LogContext.Push("Key1", "Value1"))
|
|
{
|
|
using (LogContext.Push("Key1", "Value2"))
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current.Count, Is.EqualTo(1));
|
|
Assert.That(current["Key1"], Is.EqualTo("Value2"));
|
|
}
|
|
|
|
// 释放后应该恢复原值
|
|
var restored = LogContext.Current;
|
|
Assert.That(restored["Key1"], Is.EqualTo("Value1"));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Dispose_ShouldRestorePreviousValue()
|
|
{
|
|
using (LogContext.Push("Key1", "Value1"))
|
|
{
|
|
Assert.That(LogContext.Current["Key1"], Is.EqualTo("Value1"));
|
|
}
|
|
|
|
// 释放后应该清空
|
|
Assert.That(LogContext.Current.Count, Is.EqualTo(0));
|
|
}
|
|
|
|
[Test]
|
|
public void Clear_ShouldRemoveAllProperties()
|
|
{
|
|
using (LogContext.Push("Key1", "Value1"))
|
|
{
|
|
using (LogContext.Push("Key2", "Value2"))
|
|
{
|
|
LogContext.Clear();
|
|
|
|
Assert.That(LogContext.Current.Count, Is.EqualTo(0));
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithNullKey_ShouldThrowArgumentException()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => LogContext.Push(null!, "Value"));
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithEmptyKey_ShouldThrowArgumentException()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => LogContext.Push("", "Value"));
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithWhitespaceKey_ShouldThrowArgumentException()
|
|
{
|
|
Assert.Throws<ArgumentException>(() => LogContext.Push(" ", "Value"));
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithNullValue_ShouldWork()
|
|
{
|
|
using (LogContext.Push("Key1", null))
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current.Count, Is.EqualTo(1));
|
|
Assert.That(current["Key1"], Is.Null);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public async Task Push_InAsyncContext_ShouldIsolateAcrossThreads()
|
|
{
|
|
var task1Values = new List<object?>();
|
|
var task2Values = new List<object?>();
|
|
|
|
var task1 = Task.Run(() =>
|
|
{
|
|
using (LogContext.Push("TaskId", "Task1"))
|
|
{
|
|
task1Values.Add(LogContext.Current["TaskId"]);
|
|
Task.Delay(50).Wait();
|
|
task1Values.Add(LogContext.Current["TaskId"]);
|
|
}
|
|
});
|
|
|
|
var task2 = Task.Run(() =>
|
|
{
|
|
using (LogContext.Push("TaskId", "Task2"))
|
|
{
|
|
task2Values.Add(LogContext.Current["TaskId"]);
|
|
Task.Delay(50).Wait();
|
|
task2Values.Add(LogContext.Current["TaskId"]);
|
|
}
|
|
});
|
|
|
|
await Task.WhenAll(task1, task2);
|
|
|
|
Assert.That(task1Values, Has.All.EqualTo("Task1"));
|
|
Assert.That(task2Values, Has.All.EqualTo("Task2"));
|
|
}
|
|
|
|
[Test]
|
|
public void Push_WithComplexObject_ShouldStoreReference()
|
|
{
|
|
var obj = new { Name = "Test", Value = 123 };
|
|
|
|
using (LogContext.Push("Object", obj))
|
|
{
|
|
var current = LogContext.Current;
|
|
|
|
Assert.That(current["Object"], Is.SameAs(obj));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Push_MultipleDispose_ShouldBeIdempotent()
|
|
{
|
|
var disposable = LogContext.Push("Key1", "Value1");
|
|
|
|
disposable.Dispose();
|
|
disposable.Dispose(); // 第二次调用不应该抛出异常
|
|
|
|
Assert.That(LogContext.Current.Count, Is.EqualTo(0));
|
|
}
|
|
} |