using Microsoft.Extensions.Logging;
using MongoDB.Bson.Serialization;
using MongoDB.Driver.Linq;
namespace Dpz.Core.ServiceTest;
[TestFixture]
public class UnitOfWorkTest : Basic
{
private class UnitOfWorkTestEntity : BaseEntity
{
public string Value { get; set; } = "";
}
private class UnitOfWorkTestEntity2 : BaseEntity
{
public string Value { get; set; } = "";
}
[Test]
public async Task TransactionTestAsync()
{
using var uow = GetService<IUnitOfWork>();
var repository1 = uow.GetRepository<UnitOfWorkTestEntity>();
var repository2 = uow.GetRepository<UnitOfWorkTestEntity2>();
var logger = GetService<ILogger<UnitOfWorkTest>>();
uow.Begin();
await repository1.DeleteAsync(x => true);
await repository2.DeleteAsync(x => true);
var entity1 = new UnitOfWorkTestEntity { Value = Guid.NewGuid().ToString("N") };
await repository1.InsertAsync(entity1);
var entity2 = new UnitOfWorkTestEntity2 { Value = Guid.NewGuid().ToString("N") };
await repository2.InsertAsync(entity2);
logger.LogInformation("entity1 value:{Entity1}", entity1.Value);
logger.LogInformation("entity2 value:{Entity2}", entity2.Value);
await uow.CommitAsync();
using var uow2 = GetService<IUnitOfWork>();
var repository3 = uow2.GetRepository<UnitOfWorkTestEntity>();
var repository4 = uow2.GetRepository<UnitOfWorkTestEntity2>();
var guid1 = Guid.NewGuid().ToString("N");
var guid2 = Guid.NewGuid().ToString("N");
try
{
var list1 = await repository3.SearchFor(x => true).ToListAsync();
Assert.That(list1, Is.Not.Null);
Assert.That(list1, Is.Not.Empty);
var list2 = await repository4.SearchFor(x => true).ToListAsync();
Assert.That(list2, Is.Not.Null);
Assert.That(list2, Is.Not.Empty);
uow2.Begin();
var entity3 = new UnitOfWorkTestEntity { Value = guid1 };
var entity4 = new UnitOfWorkTestEntity2 { Value = guid2 };
await repository3.InsertAsync(entity3);
await repository4.InsertAsync(entity4);
var r1 = await repository3.SearchFor(x => x.Value == guid1).FirstOrDefaultAsync();
Assert.That(r1, Is.Not.Null);
var r2 = await repository4.SearchFor(x => x.Value == guid2).FirstOrDefaultAsync();
Assert.That(r2, Is.Not.Null);
logger.LogInformation("fail entity3 value:{Entity3}", entity3.Value);
logger.LogInformation("fail entity4 value:{Entity4}", entity4.Value);
throw new Exception();
}
catch (Exception)
{
await uow2.RollbackAsync();
}
var repo1 = new Repository<UnitOfWorkTestEntity>(ConnectionString);
var repo2 = new Repository<UnitOfWorkTestEntity2>(ConnectionString);
var result1 = await repo1.SearchFor(x => x.Value == guid1).FirstOrDefaultAsync();
Assert.That(result1, Is.Null);
var result2 = await repo2.SearchFor(x => x.Value == guid2).FirstOrDefaultAsync();
Assert.That(result2, Is.Null);
}
public void Test()
{
var serializerRegistry = BsonSerializer.SerializerRegistry;
var documentSerializer = serializerRegistry.GetSerializer<SteamGame>();
var update = Builders<SteamGame>.Update.Set(x => x.PlayTime, 100u);
var updateArgs = new RenderArgs<SteamGame>(documentSerializer, serializerRegistry);
Console.WriteLine(update.Render(updateArgs));
update = update.Set(x => x.LastUpdateTime, DateTime.Now);
Console.WriteLine(update.Render(updateArgs));
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个使用NUnit测试框架编写的单元测试类,主要用于测试工作单元(Unit of Work)模式的事务功能。让我逐部分解释这个代码:
类结构
[TestFixture]
public class UnitOfWorkTest : Basic
- 这是一个测试类,继承自
Basic基类 - 使用
[TestFixture]属性标记为NUnit测试固件
测试实体类
private class UnitOfWorkTestEntity : BaseEntity
{
public string Value { get; set; } = "";
}
private class UnitOfWorkTestEntity2 : BaseEntity
{
public string Value { get; set; } = "";
}
- 定义了两个测试用的实体类,都继承自
BaseEntity - 每个实体都有一个
Value属性用于测试
主要测试方法:TransactionTestAsync()
这个方法测试了工作单元的事务功能,包括提交和回滚:
第一部分:成功的事务提交
using var uow = GetService<IUnitOfWork>();
var repository1 = uow.GetRepository<UnitOfWorkTestEntity>();
var repository2 = uow.GetRepository<UnitOfWorkTestEntity2>();
uow.Begin();
await repository1.DeleteAsync(x => true); // 清空数据
await repository2.DeleteAsync(x => true);
// 插入新数据
var entity1 = new UnitOfWorkTestEntity { Value = Guid.NewGuid().ToString("N") };
await repository1.InsertAsync(entity1);
var entity2 = new UnitOfWorkTestEntity2 { Value = Guid.NewGuid().ToString("N") };
await repository2.InsertAsync(entity2);
await uow.CommitAsync(); // 提交事务
第二部分:事务回滚测试
using var uow2 = GetService<IUnitOfWork>();
// ... 获取仓储和生成测试数据
try
{
// 验证之前提交的数据存在
var list1 = await repository3.SearchFor(x => true).ToListAsync();
Assert.That(list1, Is.Not.Null);
Assert.That(list1, Is.Not.Empty);
// 开始新事务并插入数据
uow2.Begin();
await repository3.InsertAsync(entity3);
await repository4.InsertAsync(entity4);
// 验证在事务中能查询到数据
var r1 = await repository3.SearchFor(x => x.Value == guid1).FirstOrDefaultAsync();
Assert.That(r1, Is.Not.Null);
throw new Exception(); // 模拟异常
}
catch (Exception)
{
await uow2.RollbackAsync(); // 回滚事务
}
第三部分:验证回滚效果
var repo1 = new Repository<UnitOfWorkTestEntity>(ConnectionString);
var repo2 = new Repository<UnitOfWorkTestEntity2>(ConnectionString);
// 验证回滚后数据不存在
var result1 = await repo1.SearchFor(x => x.Value == guid1).FirstOrDefaultAsync();
Assert.That(result1, Is.Null);
var result2 = await repo2.SearchFor(x => x.Value == guid2).FirstOrDefaultAsync();
Assert.That(result2, Is.Null);
Test()方法
这是一个简单的测试方法,演示了MongoDB的更新操作构建:
public void Test()
{
var serializerRegistry = BsonSerializer.SerializerRegistry;
var documentSerializer = serializerRegistry.GetSerializer<SteamGame>();
var update = Builders<SteamGame>.Update.Set(x => x.PlayTime, 100u);
var updateArgs = new RenderArgs<SteamGame>(documentSerializer, serializerRegistry);
Console.WriteLine(update.Render(updateArgs)); // 输出更新语句
update = update.Set(x => x.LastUpdateTime, DateTime.Now);
Console.WriteLine(update.Render(updateArgs)); // 输出链式更新语句
}
总结
这个测试类的主要目的是:
- 测试事务提交:验证工作单元能够正确提交多个仓储的操作
- 测试事务回滚:验证当发生异常时,工作单元能够正确回滚所有操作
- 测试数据一致性:确保事务操作后数据状态的正确性
- 演示MongoDB更新操作:展示如何构建和渲染更新语句
这是一个典型的集成测试,用于验证工作单元模式在实际数据库操作中的正确性。
AI 正在分析代码…
评论加载中...