Moq Params TargetParameterCountException:参数计数不匹配exception

以下是我的通用基础存储库接口

public interface IRepository { IQueryable AllIncluding(params Expression<Func>[] includeProperties); } 

我的实体

 public class Sdk { public Sdk() { this.Identifier = Guid.NewGuid().ToString(); } public virtual ICollection AccessibleResources { get; set; } public string Identifier { get; set; } } 

以下是具体的回购

 public interface ISdkRepository : IRepository { } 

现在我正在尝试使用moq测试控制器

以下是我试图测试的代码

 public ActionResult GetResources(string clientId) { var sdkObject = sdkRepository .AllIncluding(k => k.AccessibleResources) .SingleOrDefault(k => k.Identifier == clientId); if (sdkObject == null) throw new ApplicationException("Sdk Not Found"); return Json(sdkObject.AccessibleResources.ToList()); } 

使用以下测试

 [Test] public void Can_Get_GetResources() { var cid = Guid.NewGuid().ToString(); var mockRepo = new Moq.Mock(); var sdks = new HashSet() { new Sdk() { Identifier = cid, AccessibleResources = new HashSet() { new Resource() { Id = Guid.NewGuid(), Description = "This is sdk" } } } }; mockRepo.Setup(k => k. AllIncluding(It.IsAny<Expression<Func>[]>())) .Returns(sdks.AsQueryable); var sdkCtrl = new SdksController(mockRepo.Object); var returnedJson=sdkCtrl.GetResources(cid); returnedJson.ToString(); } 

它扔了:

System.Reflection.TargetParameterCountException:参数计数不匹配

不知道为什么?

我认为你在Moq遇到了一些限制。 它不能很好地处理表达式参数,因为它可以作为值本身传递表达式。 Moq无法知道要解析的表达式的哪个部分以及签名的一部分。

另外,我不记得Moq如何处理params xx [],但你很可能在这里遇到两个问题的组合。

您是否能够创建一个将表达式公开为属性的类? 如果是这样,可以更改AllIncluding的签名并告诉Moq匹配该类的任何实例。

更新

在回答时,这是一个限制,但现在是可能的。 请参阅Oleksandr Lytvyn的回答

虽然有一个标记为已接受的答案,但我相信有一种方法可以正确地模拟您的存储库。

代替

 mockRepo.Setup(k => k.AllIncluding(It.IsAny>[]>())) .Returns(sdks.AsQueryable); 

请用

 mockRepo.Setup(k => k.AllIncluding(It.IsAny>[]>())) .Returns((Expression>[] includeProperties) => sdks.AsQueryable()); 

解决此问题的另一个解决方案是使用: .AsQueryable()而不是.AsQueryable

对于寻找答案的其他人,我的解决方案是在Setup添加与Returns表达式中相同数量的参数。

例如:

不使用不同的参数计数

 mock.Setup(x => x.DoSomething(It.IsAny(), It.IsAny())) .Returns((string s) => s.ToLower()); 

Setup中的Returns表达式中使用相同数量的args

 mock.Setup(x => x.DoSomething(It.IsAny())) .Returns((string s1, string s2) => s1.ToLower());