refactor(swap-test): 抽取 TestableSwapEodPositionService 公共基类收敛重复 Stub

- 新建 TestableSwapEodPositionService 收敛 8/8 Stub 重复的高频 override
  (PersistEodSwapPosition/SaveAllChanges/GetCurrencyRate/AddClientCash)
  + 统一 OptUserInfo 构造 + PersistedPositions/SaveChangesCount 输出捕获
- SwapEodPositionService.DealInterests 改 protected virtual(行为零变化)
- 8 个 ScenarioTest 改为继承基类,删除重复 override
- 消灭 DealInterestsScenarioTest/DealInterestsGoldenReplayTest 的反射调用
  (typeof().GetMethod().Invoke → 直接调用 DealInterests)

验证:dotnet build 0 错误;dotnet test SwapModule 284通过/6跳过/0失败
This commit is contained in:
hjhan
2026-07-23 11:16:11 +08:00
parent 63d9decd17
commit 7b007bddfa
10 changed files with 109 additions and 109 deletions
@@ -40,31 +40,12 @@ namespace YLErp.Modules.SwapModule
/// - PersistEodSwapPosition:收集到列表而非写库
/// - GetCurrencyRate:返回 1.0(本币)
/// </summary>
private sealed class StubEodPositionService : SwapEodPositionService
private sealed class StubEodPositionService : TestableSwapEodPositionService
{
public List<eod_swap_position> PersistedPositions { get; } = new();
public StubEodPositionService() : base(new OptUserInfo(0, nameof(DealInterestsScenarioTest), OptUserFrom.UnitTest))
public StubEodPositionService() : base(nameof(DealInterestsScenarioTest))
{
}
protected override void PersistEodSwapPosition(eod_swap_position position)
{
// 收集到列表,不写库。如果 id=0 模拟新增。
if (position.id == 0) position.id = PersistedPositions.Count + 1;
PersistedPositions.Add(position);
}
protected override void SaveAllChanges()
{
// 不做任何事(内存模式)
}
protected override double GetCurrencyRate(string quoteCurrency, string settlementCurrency, DateTime valueDate, bool seekPreday, CurrencyRateType currencyRateType)
{
return 1.0; // 本币,汇率=1
}
// override CalcSwapInterests:用真实 SwapDealService 算(固定利率不需 mock 浮动利率)
// 生产代码默认实现也是 new SwapDealService(this).GetInterests(...),这里保持一致
// 但 SwapDealService 内部 TryGetFloatRate 会连库——固定利率(FloatRateUnderlyingCode=null)不会触发
@@ -94,21 +75,16 @@ namespace YLErp.Modules.SwapModule
return PersistedPositions.LastOrDefault();
}
// public 包装:调用 DealInterests(通过反射,因为参数太多不好包
// public 包装:直接调用 protected virtual DealInterests(已改为 virtual,无需反射
public void ExecuteDealInterests(
List<swap_position> interestList, List<eod_swap_position> eodPositions,
DateTime settleDate, trade td, List<swap_flow_event> flowEvents,
decimal posiLongNational, decimal posiShortNational,
decimal closeNational, decimal grossPrice, decimal orginPv)
{
var method = typeof(SwapEodPositionService).GetMethod("DealInterests",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
method.Invoke(this, new object[]
{
interestList, eodPositions, new List<eod_swap_position>(),
DealInterests(interestList, eodPositions, new List<eod_swap_position>(),
settleDate, td, flowEvents, new List<swap_flow_event>(), null,
posiLongNational, posiShortNational, closeNational, grossPrice, orginPv
});
posiLongNational, posiShortNational, closeNational, grossPrice, orginPv);
}
}