模拟 IOrganizationService (Dynamics CRM) 时未过滤 LINQ 查询结果

LINQ query results not filtered when mocking IOrganizationService (Dynamics CRM)

我在单元测试查询 Dynamics CRM 2015 的代码时遇到问题。

我使用 Moq 框架并模拟 IOrganizationService 如下:

IList<Account> accounts = new List<Account> {/*...*/};
IList<IEntity> expected = new List<Entity>(accounts);
var collection = new EntityCollection(expected);
var retrieveMultipleResponse = new RetrieveMultipleResponse
{
    Results = new ParameterCollection
    {
        { "EntityCollection", collection}
    }
};
var mockOrganizationService = new Mock<IOrganizationService>();
mockOrganizationService.Setup(os => os.Execute(
    It.IsAny<RetrieveMultipleRequest>())).Returns(retrieveMultipleResponse);

因此,IOrganizationService 模拟将始终return 相同的预定义帐户列表,无论请求是什么样的。

这是我要测试的代码:

var query = serviceContext.AccountSet.Where(
                a => a.AccountId != null && a.AccountId.Value == guid)
var account = query.FirstOrDefault();

当针对真实 CRM 实例执行此代码时,它按预期工作。

使用模拟 IOrganizationService,代码不再有效。在调试器中,我可以看到 AccountSet returns 是预期的帐户列表(我在模拟期间设置的那个)。但是,Where 方法似乎没有执行,query 包含所有帐户实体。所以,调用 FirstOrDefault return 只是第一个,而不是调用 Where 方法的结果。

如果我按如下方式修改代码,它在单元测试期间也开始工作:

var query = serviceContext.AccountSet.ToList().Where(
                    a => a.AccountId != null && a.AccountId.Value == guid)
var account = query.FirstOrDefault();

如果我没理解错的话,这段代码会检索所有帐户,并在本地(而不是在 CRM 中)过滤它们。这对于单元测试来说很好,但在实际应用中是不可接受的。

任何人都可以告诉我做错了什么吗?谢谢!

编辑

我们最终模拟了 serviceContext,因为我们直接从客户端代码调用它的方法(或属性),而不是 IOrganizationService 上的方法(或属性)。我认为只有当我们要测试的代码直接使用 IOrganizationService 而不是通过 serviceContext 时,模拟 IOrganizationService 才有意义。否则,我们会有类似两级模拟的东西,它会变得很乱。

请尝试FakeXrmEasy。有一些介绍视频和许多不同的测试示例。

通过使用 FakeXrmEasy,框架已经处理了模拟,因此减少了仅用于设置测试的样板代码量。

我从 2014 年开始研究它,它是 MIT 许可的。实际上,如果有人愿意为该项目做出贡献,那就太棒了! :)

编辑:只是 adding a link 到一个博客 post,它将 FakeXrmEasy 与其他 .NET 模拟框架进行比较。目的无非就是能够为 Dynamics CRM 完成尽可能多的工作。对于其他 .NET 模拟框架,每次模拟的内容基本上太多了。

Where 子句成为针对 OrganizationService 执行的查询的一部分,在您的情况下,无论条件如何,它总是被模拟为 return 完整的 accounts 列表.您可以向您的最小起订量添加更多逻辑,但通常这在单元测试中不是必需的,因为您的目标是测试您的业务逻辑,而不是您模拟 OrganizationService.

的能力