You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FakeXrmEasy单元测试中模拟Dynamics 365货币字段本位币重算?

解决FakeXrmEasy中货币字段本位币自动重算的问题

我之前在FakeXrmEasy里测试Dynamics 365货币字段的时候,也碰到过一模一样的问题——系统自动生成的_Base本位币字段不会自动计算,导致求和结果不符合预期。下面给你分享几个实用的解决思路:

1. 简单场景:手动设置本位币字段

如果你的测试场景比较简单(比如固定汇率、不需要模拟复杂的货币转换逻辑),最直接的办法就是在设置普通货币字段的同时,手动给_Base字段赋值:

// 设置业务货币字段
localAccount.turnover = new Money(100);
// 根据测试场景的汇率手动设置本位币字段(这里假设汇率是1:1)
localAccount.turnover_Base = new Money(100);

这种方式快速高效,适合只需要验证求和逻辑本身,不需要模拟系统货币转换流程的测试用例。

2. 贴近实际:模拟系统货币重算插件

在Dynamics 365实际环境中,本位币字段的计算是由系统内置插件完成的——它会根据实体的货币类型(currencyid)和汇率表中的汇率,自动转换并填充_Base字段。我们可以在FakeXrmEasy中注册一个模拟插件,还原这个逻辑:

第一步:编写模拟转换插件

public class CurrencyConversionSimulatorPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        var targetEntity = context.InputParameters["Target"] as Entity;

        // 只处理Account实体的turnover字段更新/创建
        if (targetEntity?.LogicalName != "account" || !targetEntity.Contains("turnover"))
            return;

        // 获取业务货币值
        var transactionCurrencyValue = (Money)targetEntity["turnover"];
        
        // 模拟汇率获取逻辑:可以固定值,也可以从测试数据中查询Currency实体的汇率
        // 这里我们用固定汇率1.2来举例
        decimal exchangeRate = 1.2m;
        
        // 计算并设置本位币字段
        targetEntity["turnover_Base"] = new Money(transactionCurrencyValue.Value * exchangeRate);
    }
}

第二步:在测试中注册插件

在你的测试初始化代码里,把这个插件注册到对应的实体和操作上:

// 初始化FakeXrmEasy上下文
var fakedContext = new XrmFakedContext();

// 注册插件,模拟系统在PreOperation阶段处理Create和Update操作时的货币转换
fakedContext.RegisterPluginStep<CurrencyConversionSimulatorPlugin>(
    entityLogicalName: "account",
    stage: PluginStage.PreOperation,
    messageName: MessageName.Create,
    messageName: MessageName.Update
);

// 创建测试账户
var testAccount = new Account
{
    Name = "Test Account",
    turnover = new Money(100)
};
fakedContext.Create(testAccount);

// 现在查询并求和,就能得到正确的本位币值(100*1.2=120)
var allAccounts = fakedContext.CreateQuery<Account>().ToList();
var sumOfTurnovers = allAccounts.Sum(s => s.turnover_Base?.Value ?? 0);
// sumOfTurnovers的值应该是120

这种方式的好处是完全模拟了Dynamics 365的实际运行逻辑,测试结果更贴近生产环境,适合需要验证复杂业务流程的场景。

3. 进阶优化:动态获取测试汇率

如果你的测试需要模拟不同的货币类型和汇率,可以在测试数据中预先创建currency实体,然后在插件中通过组织服务查询对应的汇率:

// 在插件中获取组织服务
var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);

// 获取当前账户的货币类型ID
var currencyId = targetEntity.GetAttributeValue<Guid>("currencyid");
// 查询对应的Currency实体获取汇率
var currency = service.Retrieve("currency", currencyId, new ColumnSet("exchangerate"));
decimal exchangeRate = currency.GetAttributeValue<decimal>("exchangerate");

这样就能根据测试中设置的不同货币,动态计算本位币值,让测试更灵活。

内容的提问来源于stack exchange,提问作者A.D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 16:48:13