Moq Params TargetParameterCountException:参数数量不匹配异常
本文关键字:不匹配 异常 数数 参数 Params TargetParameterCountException Moq | 更新日期: 2023-09-27 18:08:31
以下是我的通用基础存储库接口
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; }
}
和以下是具体的repo
public interface ISdkRepository : IRepository<Sdk>
{
}
现在我试图测试一个控制器,使用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<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();
}
,它抛出:
System.Reflection。TargetParameterCountException:参数计数不匹配
不知道为什么?
虽然有一个答案被标记为接受,但我相信有一种方法可以正确地模拟您的存储库。
不是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());
解决此问题的另一种方法是使用:.AsQueryable()
代替.AsQueryable
。
我认为你在Moq上遇到了一些限制。它不能很好地处理表达式参数,因为它本身可以作为值传递表达式。Moq没有办法知道表达式的哪一部分是要解析的,哪一部分是签名的。
另外,我不记得Moq处理参数xx[]有多好,但很有可能你在这里有两个问题的组合。
您是否能够创建一个类,将表达式集作为属性公开?如果是这样的话,可以修改allinclude的签名,并告诉Moq匹配该类的任何实例。
在回答这个问题的时候,这是一个限制,但现在是可能的。参见Oleksandr Lytvyn的回答
对于其他寻找答案的人来说,我的解决方案是在Setup
中添加与Returns
中表达式相同数量的参数。
:
不能使用不同的参数计数
mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
.Returns((string s) => s.ToLower());
在Returns
的表达式中使用与Setup
相同数量的参数
mock.Setup(x => x.DoSomething(It.IsAny<string>()))
.Returns((string s1, string s2) => s1.ToLower());