如何使用MSFakes模拟ODataClient的Expand方法?
我之前也碰到过类似的Dynamics 365 OData客户端用MSFakes模拟的坑,结合你的报错信息和操作步骤,核心问题应该是没有给每个Insurance实例的关联导航属性设置有效的模拟对象,而不是只模拟Accounts集合的Getter。给你几个具体的解决步骤:
1. 确认导航属性的Shim方法并绑定模拟对象
首先要明确:Expand是针对导航属性的,不是外键字段。你需要给每个模拟的Ecr_insurance实例的Account_id导航属性(不管是lambda还是字符串形式的Expand)设置一个非null的模拟Account对象,而不是只单独模拟Accounts的集合Getter。
举个具体的代码示例:
// 1. 先模拟一个Account实例,设置必要的属性(比如Id) var mockAccount = new ShimAccount { IdGet = () => Guid.NewGuid(), // 可以根据测试需求添加其他属性的模拟 NameGet = () => "Test Account" }; // 2. 模拟Insurance实例,绑定导航属性到上面的mockAccount var mockInsurance = new ShimEcr_insurance { IdGet = () => Guid.NewGuid(), // 重点:这里要对应导航属性的Getter方法,确保返回非null的mockAccount Account_idGet = () => mockAccount }; // 3. 把模拟的Insurance添加到Insurances集合的Shim中 ShimEcr_insuranceCollection.AllInstances.GetEnumerator = () => new List<ShimEcr_insurance> { mockInsurance }.GetEnumerator();
2. 核对MSFakes生成的Shim方法命名
有时候自动生成的Shim类里,导航属性的Getter方法命名可能和你预期的不一样,比如如果导航属性是可空的,或者生成时用了不同的命名规则。你可以在解决方案的Fakes目录下找到ShimEcr_insurance的定义,确认导航属性对应的Getter方法是不是Account_idGet——比如有没有可能是GetAccount_id()或者其他形式?确保你Shim的是正确的方法。
3. 确保所有返回的Insurance实例都设置了导航属性
你的堆栈报错显示在Linq遍历集合时出现NullReference,说明至少有一个返回的Ecr_insurance实例的Account_id是null。所以要检查:
- 所有被Shim返回的Insurance对象,它们的
Account_id导航属性都被设置了有效的模拟Account,不能有遗漏。 - 如果你的测试场景需要部分Insurance没有关联Account,那也要显式设置
Account_idGet = () => null,而不是留空让它默认返回null(MSFakes的Shim默认可能不会处理,导致原始属性返回null)。
4. 排查Expand的命名是否正确
虽然你两种形式都报错,但还是要确认一下:Dynamics 365 OData的导航属性命名通常是驼峰或 PascalCase,比如如果实体是Account,导航属性可能是account(字符串形式)或者Account(lambda形式),而不是account_id——会不会是你把外键字段名当成了导航属性名?如果是这个问题,即使Shim正确,也会因为找不到对应的导航属性而报错。你可以去Dynamics 365的元数据里确认导航属性的准确名称。
内容的提问来源于stack exchange,提问作者kor_

