2011-09-14 66 views
10

以下是我的通用基仓库接口起订量PARAMS TargetParameterCountException:参数数量不匹配异常

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

我的实体

public class Sdk 
{ 
    public Sdk() 
    { 
     this.Identifier = Guid.NewGuid().ToString(); 
    } 

    public virtual ICollection<Resource> AccessibleResources { get; set; } 

    public string Identifier { get; set; }  
} 

和下面就是具体的回购

public interface ISdkRepository : IRepository<Sdk> 
{ 
} 

现在的我试图测试一个控制器,使用moq

以下是我尝试使用下面的测试

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

测试

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()); 
    } 

的代码,它抛出:

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

不知道为什么?

+0

与相同量的在Returns表达ARGS的工作如可你粘贴堆栈跟踪? – Raghu

回答

4

我认为你在这里与Moq碰到了一些限制。它不能很好地处理表达式参数,因为它可以将表达式作为值本身传递。 Moq没有办法知道该表达式的哪一部分是要解决的,哪些是签名的一部分。

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

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

更新

在回答这个问题的时间限制,但现在是可能的。查看答案由Oleksandr Lytvyn

+0

请查看Oleksandr Lytvyn的答案。 – Marcel

28

虽然有一个答案被标记为接受,我相信有一种方法来正确地嘲笑你的存储库。

代替

mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>())) 
        .Returns(sdks.AsQueryable); 

请使用

mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>())) 
        .Returns((Expression<Func<Sdk, 
         object>>[] includeProperties) => sdks.AsQueryable()); 
+1

它拯救了我的一天)我的方法完全一样,你的提案有效! –

+0

谢谢!救了我戳 – trailmax

+0

太棒了!工作。是否有解释它如何工作(这实际上是这样做的)? – Marcel

7

另一种解决方案来解决这个问题是使用:.AsQueryable()代替.AsQueryable

0

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

例如:

不能与不同的参数工作计数

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

Setup

mock.Setup(x => x.DoSomething(It.IsAny<string>())) 
       .Returns((string s1, string s2) => s1.ToLower()); 
相关问题